@burdenoff/fe-libs 2026.904.12 → 2026.904.13
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/exportConversation.d.ts +8 -0
- package/dist/shared/assistant/exportConversation.d.ts.map +1 -0
- package/dist/shared/assistant/exportConversation.js +47 -0
- package/dist/shared/assistant/i18n.d.ts +0 -4
- package/dist/shared/assistant/i18n.d.ts.map +1 -1
- package/dist/shared/assistant/i18n.js +21 -21
- package/dist/shared/assistant/index.d.ts +6 -0
- package/dist/shared/assistant/index.d.ts.map +1 -1
- package/dist/shared/assistant/product.d.ts +81 -0
- package/dist/shared/assistant/product.d.ts.map +1 -0
- package/dist/shared/assistant/product.js +34 -0
- package/dist/shared/assistant/ui/AssistantConversationList.d.ts +3 -0
- package/dist/shared/assistant/ui/AssistantConversationList.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantConversationList.js +159 -0
- package/dist/shared/assistant/ui/AssistantEmptyState.d.ts +16 -0
- package/dist/shared/assistant/ui/AssistantEmptyState.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantEmptyState.js +38 -0
- package/dist/shared/assistant/ui/AssistantHeader.d.ts +25 -0
- package/dist/shared/assistant/ui/AssistantHeader.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantHeader.js +75 -0
- package/dist/shared/assistant/ui/AssistantMoreMenu.d.ts +32 -0
- package/dist/shared/assistant/ui/AssistantMoreMenu.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantMoreMenu.js +121 -0
- package/dist/shared-assistant.js +45 -39
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Conversation } from './conversation';
|
|
2
|
+
export declare function exportConversation(conversation: Conversation, format: "json" | "markdown"): {
|
|
3
|
+
content: string;
|
|
4
|
+
filename: string;
|
|
5
|
+
mimeType: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function downloadFile(content: string, filename: string, mimeType: string): void;
|
|
8
|
+
//# sourceMappingURL=exportConversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exportConversation.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/exportConversation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,GAAG,UAAU,GAC1B;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAuEzD;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,IAAI,CAUN"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { isVoiceTurn as e } from "./voice/turnVisibility.js";
|
|
2
|
+
//#region src/shared/assistant/exportConversation.ts
|
|
3
|
+
function t(t, n) {
|
|
4
|
+
let r = t.title.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-|-$/g, "").toLowerCase(), i = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
5
|
+
if (n === "json") {
|
|
6
|
+
let n = {
|
|
7
|
+
id: t.id,
|
|
8
|
+
title: t.title,
|
|
9
|
+
mode: t.mode,
|
|
10
|
+
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11
|
+
backendSessionId: t.backendSessionId ?? null,
|
|
12
|
+
messages: t.messages.map((t) => ({
|
|
13
|
+
role: t.role,
|
|
14
|
+
channel: e(t) ? "voice" : "chat",
|
|
15
|
+
content: t.content,
|
|
16
|
+
timestamp: t.timestamp,
|
|
17
|
+
tokens: t.tokens
|
|
18
|
+
}))
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
content: JSON.stringify(n, null, 2),
|
|
22
|
+
filename: `${r}-${i}.json`,
|
|
23
|
+
mimeType: "application/json"
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
let a = [
|
|
27
|
+
`# ${t.title}`,
|
|
28
|
+
"",
|
|
29
|
+
`> Mode: ${t.mode} | Exported: ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
|
|
30
|
+
""
|
|
31
|
+
];
|
|
32
|
+
for (let n of t.messages) {
|
|
33
|
+
let t = n.role === "system" ? "Note" : n.role === "user" ? "You" : "Assistant";
|
|
34
|
+
a.push(`## ${t}${e(n) ? " (spoken)" : ""}`), a.push(""), a.push(n.content), a.push("");
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
content: a.join("\n"),
|
|
38
|
+
filename: `${r}-${i}.md`,
|
|
39
|
+
mimeType: "text/markdown"
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function n(e, t, n) {
|
|
43
|
+
let r = new Blob([e], { type: n }), i = URL.createObjectURL(r), a = document.createElement("a");
|
|
44
|
+
a.href = i, a.download = t, document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(i);
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { n as downloadFile, t as exportConversation };
|
|
@@ -25,10 +25,6 @@ import { ReactNode } from 'react';
|
|
|
25
25
|
* without rendering anything.
|
|
26
26
|
*/
|
|
27
27
|
export declare function assistantTranslationKey(namespace: string, key: string): string;
|
|
28
|
-
export interface AssistantI18nValue {
|
|
29
|
-
/** Product id, e.g. `healthybowl`. Matches the id in shared/config/products. */
|
|
30
|
-
namespace: string;
|
|
31
|
-
}
|
|
32
28
|
export interface AssistantI18nProviderProps {
|
|
33
29
|
namespace: string;
|
|
34
30
|
children: ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/i18n.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/i18n.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKpD;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,MAAM,CAER;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,QAAQ,GACT,EAAE,0BAA0B,2CAa5B;AAED,mEAAmE;AACnE,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,IAAI,CAEzD;AAED,MAAM,MAAM,WAAW,GAAG,CACxB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KACrC,MAAM,CAAC;AAIZ;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,IAAI,WAAW,CA4B5C"}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
import { useI18n as e } from "../providers/shell/I18nProvider.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { AssistantProductProvider as t, useAssistantProductOrNull as n } from "./product.js";
|
|
3
|
+
import { useCallback as r } from "react";
|
|
4
|
+
import { jsx as i } from "react/jsx-runtime";
|
|
4
5
|
//#region src/shared/assistant/i18n.tsx
|
|
5
|
-
function
|
|
6
|
+
function a(e, t) {
|
|
6
7
|
return `${e}.assistant.${t}`;
|
|
7
8
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
children: t
|
|
9
|
+
function o({ namespace: e, children: n }) {
|
|
10
|
+
return /* @__PURE__ */ i(t, {
|
|
11
|
+
product: e,
|
|
12
|
+
modes: [],
|
|
13
|
+
children: n
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
|
-
function
|
|
17
|
-
return
|
|
16
|
+
function s() {
|
|
17
|
+
return n()?.product ?? null;
|
|
18
18
|
}
|
|
19
|
-
var
|
|
20
|
-
function
|
|
21
|
-
let { t } = e(),
|
|
22
|
-
return
|
|
23
|
-
if (
|
|
24
|
-
let
|
|
25
|
-
return
|
|
26
|
-
}, [t,
|
|
19
|
+
var c = !1;
|
|
20
|
+
function l() {
|
|
21
|
+
let { t } = e(), n = s();
|
|
22
|
+
return n === null && !c && (c = !0, console.error("[assistant] No AssistantI18nProvider mounted — assistant copy will render in English for every locale. Wrap the assistant in <AssistantI18nProvider namespace=\"<product>\">.")), r((e, r, i) => {
|
|
23
|
+
if (n === null) return u(r, i);
|
|
24
|
+
let o = a(n, e), s = t(o);
|
|
25
|
+
return u(s === o ? r : s, i);
|
|
26
|
+
}, [t, n]);
|
|
27
27
|
}
|
|
28
|
-
function
|
|
28
|
+
function u(e, t) {
|
|
29
29
|
return t ? Object.entries(t).reduce((e, [t, n]) => e.replace(RegExp(`\\{\\{${t}\\}\\}`, "g"), String(n)), e) : e;
|
|
30
30
|
}
|
|
31
31
|
//#endregion
|
|
32
|
-
export {
|
|
32
|
+
export { o as AssistantI18nProvider, a as assistantTranslationKey, s as useAssistantI18nNamespace, l as useAssistantTr };
|
|
@@ -98,4 +98,10 @@ export * from './ui/voice/VoiceMiniController';
|
|
|
98
98
|
export * from './ui/voice/VoiceStage';
|
|
99
99
|
export * from './ui/voice/VoiceTranscriptDrawer';
|
|
100
100
|
export * from './ui/voice/VoiceWaveform';
|
|
101
|
+
export * from './product';
|
|
102
|
+
export * from './ui/AssistantMoreMenu';
|
|
103
|
+
export * from './ui/AssistantHeader';
|
|
104
|
+
export * from './ui/AssistantConversationList';
|
|
105
|
+
export * from './ui/AssistantEmptyState';
|
|
106
|
+
export * from './exportConversation';
|
|
101
107
|
//# 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"}
|
|
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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { AssistantModeConfig } from './conversation';
|
|
3
|
+
/**
|
|
4
|
+
* What a product tells the shared assistant about ITSELF.
|
|
5
|
+
*
|
|
6
|
+
* ★★ Deliberately tiny, and it should stay that way. The obvious design here is
|
|
7
|
+
* a broad capabilities object — transport, RBAC, export, artifact download,
|
|
8
|
+
* quota, branding — and it would have been wrong. Every one of those turned out
|
|
9
|
+
* to be either already shared or shareable once looked at:
|
|
10
|
+
*
|
|
11
|
+
* - `downloadAssistantArtifact` already exists in `./api`; the product's copy
|
|
12
|
+
* was a five-line adapter dropping a vestigial argument.
|
|
13
|
+
* - the conversation export service had ZERO product references.
|
|
14
|
+
* - modes, RBAC and quota are consumed by the product's own orchestrator,
|
|
15
|
+
* which composes this library rather than living inside it.
|
|
16
|
+
*
|
|
17
|
+
* What genuinely varies by product, and cannot be derived, is two things: WHICH
|
|
18
|
+
* MODES it offers, and WHAT IT CALLS THE PAGE the user is on. A field is only
|
|
19
|
+
* added here when a shared component cannot work without it and no product can
|
|
20
|
+
* supply it by any other means. An interface that grows to fit one product is
|
|
21
|
+
* how HealthyBowl's shape ends up baked into every other product's library.
|
|
22
|
+
*/
|
|
23
|
+
export interface AssistantProductCapabilities {
|
|
24
|
+
/**
|
|
25
|
+
* The modes this product offers, in display order.
|
|
26
|
+
*
|
|
27
|
+
* fe-libs owns the SHAPE (`AssistantModeConfig`); the product owns the LIST.
|
|
28
|
+
* FluidGrids offers "Build a node", HealthyBowl offers "Take action", and
|
|
29
|
+
* neither should be able to render the other's.
|
|
30
|
+
*/
|
|
31
|
+
modes: readonly AssistantModeConfig[];
|
|
32
|
+
/**
|
|
33
|
+
* A human label for where the user is right now — "Crop planning", "Workflow
|
|
34
|
+
* editor" — or null when there is nothing useful to say.
|
|
35
|
+
*
|
|
36
|
+
* Optional because it is genuinely optional: a product with no route model
|
|
37
|
+
* simply has no answer, and the empty state drops the sentence rather than
|
|
38
|
+
* inventing one. Resolving a route to an entity is deep product knowledge and
|
|
39
|
+
* a wrong answer is worse than none.
|
|
40
|
+
*/
|
|
41
|
+
describeCurrentPage?: () => string | null;
|
|
42
|
+
}
|
|
43
|
+
export interface AssistantProductValue extends AssistantProductCapabilities {
|
|
44
|
+
/**
|
|
45
|
+
* Product id, e.g. `healthybowl`. The SAME value the transport sends as
|
|
46
|
+
* `AI_ASSISTANT_PRODUCT` and the prefix for `<product>.assistant.*` keys, so
|
|
47
|
+
* "which product is this?" has exactly one answer rather than two that drift.
|
|
48
|
+
*/
|
|
49
|
+
product: string;
|
|
50
|
+
}
|
|
51
|
+
export interface AssistantProductProviderProps extends AssistantProductCapabilities {
|
|
52
|
+
product: string;
|
|
53
|
+
children: ReactNode;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Mount once, above the assistant. Everything below can ask what product it is
|
|
57
|
+
* running inside and what that product offers.
|
|
58
|
+
*/
|
|
59
|
+
export declare function AssistantProductProvider({ product, modes, describeCurrentPage, children, }: AssistantProductProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
60
|
+
/** The product in force, or null when no provider is mounted. */
|
|
61
|
+
export declare function useAssistantProductOrNull(): AssistantProductValue | null;
|
|
62
|
+
/**
|
|
63
|
+
* The product in force.
|
|
64
|
+
*
|
|
65
|
+
* ★ Returns an empty descriptor rather than throwing when no provider is
|
|
66
|
+
* mounted. A missing provider is a configuration mistake, but a throw inside
|
|
67
|
+
* render is a white screen, and a mode selector with nothing in it is a visible,
|
|
68
|
+
* survivable failure that says exactly what is wrong. `useAssistantTr` complains
|
|
69
|
+
* to the console on the same condition, so it is still findable.
|
|
70
|
+
*/
|
|
71
|
+
export declare function useAssistantProduct(): AssistantProductValue;
|
|
72
|
+
/**
|
|
73
|
+
* The mode a product would show for an id, falling back to its first.
|
|
74
|
+
*
|
|
75
|
+
* Shared because two components need exactly this and got it slightly
|
|
76
|
+
* differently: a persisted mode can name something the product no longer offers
|
|
77
|
+
* — a flag turned off, or a conversation restored from another build — and
|
|
78
|
+
* `undefined` there renders an empty panel rather than a usable one.
|
|
79
|
+
*/
|
|
80
|
+
export declare function resolveModeConfig(modes: readonly AssistantModeConfig[], mode: string | undefined): AssistantModeConfig | undefined;
|
|
81
|
+
//# sourceMappingURL=product.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/product.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;;;OAMG;IACH,KAAK,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACtC;;;;;;;;OAQG;IACH,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAsB,SAAQ,4BAA4B;IACzE;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,MAAM,WAAW,6BAA8B,SAAQ,4BAA4B;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,KAAK,EACL,mBAAmB,EACnB,QAAQ,GACT,EAAE,6BAA6B,2CAU/B;AAED,iEAAiE;AACjE,wBAAgB,yBAAyB,IAAI,qBAAqB,GAAG,IAAI,CAExE;AAID;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,qBAAqB,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,mBAAmB,EAAE,EACrC,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,mBAAmB,GAAG,SAAS,CAEjC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createContext as e, useContext as t, useMemo as n } from "react";
|
|
2
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
3
|
+
//#region src/shared/assistant/product.tsx
|
|
4
|
+
var i = e(null);
|
|
5
|
+
function a({ product: e, modes: t, describeCurrentPage: a, children: o }) {
|
|
6
|
+
let s = n(() => ({
|
|
7
|
+
product: e,
|
|
8
|
+
modes: t,
|
|
9
|
+
describeCurrentPage: a
|
|
10
|
+
}), [
|
|
11
|
+
e,
|
|
12
|
+
t,
|
|
13
|
+
a
|
|
14
|
+
]);
|
|
15
|
+
return /* @__PURE__ */ r(i.Provider, {
|
|
16
|
+
value: s,
|
|
17
|
+
children: o
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function o() {
|
|
21
|
+
return t(i);
|
|
22
|
+
}
|
|
23
|
+
var s = {
|
|
24
|
+
product: "",
|
|
25
|
+
modes: []
|
|
26
|
+
};
|
|
27
|
+
function c() {
|
|
28
|
+
return t(i) ?? s;
|
|
29
|
+
}
|
|
30
|
+
function l(e, t) {
|
|
31
|
+
return e.find((e) => e.id === t) ?? e[0];
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { a as AssistantProductProvider, l as resolveModeConfig, c as useAssistantProduct, o as useAssistantProductOrNull };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantConversationList.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantConversationList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAc1C,eAAO,MAAM,yBAAyB,EAAE,EAgPvC,CAAC"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { chatTurns as e } from "../voice/turnVisibility.js";
|
|
2
|
+
import { useAssistantProduct as t } from "../product.js";
|
|
3
|
+
import { useAssistantTr as n } from "../i18n.js";
|
|
4
|
+
import { useAssistantStore as r } from "../store.js";
|
|
5
|
+
import { useState as i } from "react";
|
|
6
|
+
import { Check as a, MessageSquare as o, PanelLeftClose as s, Pencil as c, Plus as l, Trash2 as u } from "lucide-react";
|
|
7
|
+
import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
8
|
+
//#region src/shared/assistant/ui/AssistantConversationList.tsx
|
|
9
|
+
var m = () => {
|
|
10
|
+
let m = n(), { modes: h } = t(), { conversations: g, activeConversationId: _, processingByConversationId: v, setActiveConversation: y, setMode: b, createConversation: x, deleteConversation: S, renameConversation: C, setConversationListOpen: w } = r(), [T, E] = i(null), [D, O] = i(""), k = () => {
|
|
11
|
+
x(), w(!1);
|
|
12
|
+
}, A = (e) => {
|
|
13
|
+
let t = g.find((t) => t.id === e);
|
|
14
|
+
y(e), t && b(t.mode), w(!1);
|
|
15
|
+
}, j = (e, t) => {
|
|
16
|
+
E(e), O(t);
|
|
17
|
+
}, M = () => {
|
|
18
|
+
T && D.trim() && C(T, D.trim()), E(null);
|
|
19
|
+
}, N = (e, t) => {
|
|
20
|
+
e.stopPropagation(), S(t);
|
|
21
|
+
};
|
|
22
|
+
return /* @__PURE__ */ p("div", {
|
|
23
|
+
className: "absolute inset-0 z-10 flex flex-col bg-bg-surface animate-in slide-in-from-left-2 fade-in duration-200",
|
|
24
|
+
"data-testid": "conversation-list",
|
|
25
|
+
children: [/* @__PURE__ */ p("div", {
|
|
26
|
+
className: "flex items-center justify-between px-4 py-3 border-b border-border-default bg-bg-elevated",
|
|
27
|
+
children: [/* @__PURE__ */ f("span", {
|
|
28
|
+
className: "text-[13px] font-semibold text-text-primary",
|
|
29
|
+
children: m("conversations.title", "History")
|
|
30
|
+
}), /* @__PURE__ */ p("div", {
|
|
31
|
+
className: "flex items-center gap-0.5",
|
|
32
|
+
children: [/* @__PURE__ */ f("button", {
|
|
33
|
+
type: "button",
|
|
34
|
+
onClick: k,
|
|
35
|
+
className: "p-1.5 rounded-lg text-text-secondary hover:bg-bg-sunken transition-colors",
|
|
36
|
+
"aria-label": m("conversations.new", "New conversation"),
|
|
37
|
+
"data-testid": "new-conversation",
|
|
38
|
+
children: /* @__PURE__ */ f(l, { className: "size-4" })
|
|
39
|
+
}), /* @__PURE__ */ p("button", {
|
|
40
|
+
type: "button",
|
|
41
|
+
onClick: () => w(!1),
|
|
42
|
+
className: "flex items-center gap-1 px-2 py-1.5 rounded-lg text-text-secondary hover:bg-bg-sunken transition-colors",
|
|
43
|
+
"aria-label": m("conversations.collapse", "Collapse history"),
|
|
44
|
+
"data-testid": "collapse-conversation-list",
|
|
45
|
+
children: [/* @__PURE__ */ f(s, { className: "size-4" }), /* @__PURE__ */ f("span", {
|
|
46
|
+
className: "text-[11px] font-medium",
|
|
47
|
+
children: m("conversations.collapseLabel", "Collapse")
|
|
48
|
+
})]
|
|
49
|
+
})]
|
|
50
|
+
})]
|
|
51
|
+
}), /* @__PURE__ */ f("div", {
|
|
52
|
+
className: "flex-1 overflow-y-auto",
|
|
53
|
+
children: g.length === 0 ? /* @__PURE__ */ p("div", {
|
|
54
|
+
className: "flex flex-col items-center justify-center h-full text-center px-4",
|
|
55
|
+
children: [
|
|
56
|
+
/* @__PURE__ */ f(o, { className: "size-6 text-text-muted mb-2" }),
|
|
57
|
+
/* @__PURE__ */ f("p", {
|
|
58
|
+
className: "text-xs text-text-muted",
|
|
59
|
+
children: m("conversations.empty", "No conversations yet")
|
|
60
|
+
}),
|
|
61
|
+
/* @__PURE__ */ f("button", {
|
|
62
|
+
type: "button",
|
|
63
|
+
onClick: k,
|
|
64
|
+
className: "mt-2 text-xs text-action-primary-bg hover:underline",
|
|
65
|
+
children: m("conversations.startNew", "Start a new conversation")
|
|
66
|
+
})
|
|
67
|
+
]
|
|
68
|
+
}) : /* @__PURE__ */ f("div", {
|
|
69
|
+
className: "py-1",
|
|
70
|
+
children: g.map((t) => {
|
|
71
|
+
let n = t.id === _, r = t.id === T, i = h.find((e) => e.id === t.mode), o = e(t.messages), s = o[o.length - 1], l = o.length === 0 && t.messages.length > 0, g = v[t.id];
|
|
72
|
+
return /* @__PURE__ */ f("div", {
|
|
73
|
+
role: "button",
|
|
74
|
+
tabIndex: 0,
|
|
75
|
+
onKeyDown: (e) => {
|
|
76
|
+
(e.key === "Enter" || e.key === " ") && (e.preventDefault(), !r && A(t.id));
|
|
77
|
+
},
|
|
78
|
+
onClick: () => !r && A(t.id),
|
|
79
|
+
className: `group px-3 py-2 cursor-pointer hover:bg-bg-elevated transition-colors ${n ? "bg-bg-elevated border-l-2 border-action-primary-bg" : ""}`,
|
|
80
|
+
children: r ? /* @__PURE__ */ p("div", {
|
|
81
|
+
className: "flex items-center gap-1",
|
|
82
|
+
children: [/* @__PURE__ */ f("input", {
|
|
83
|
+
"aria-label": m("conversations.renameLabel", "Conversation title"),
|
|
84
|
+
value: D,
|
|
85
|
+
onChange: (e) => O(e.target.value),
|
|
86
|
+
onKeyDown: (e) => {
|
|
87
|
+
e.key === "Enter" && M(), e.key === "Escape" && E(null);
|
|
88
|
+
},
|
|
89
|
+
className: "flex-1 text-xs bg-bg-sunken border border-border-default rounded px-2 py-1 text-text-primary focus:outline-none focus:border-action-primary-bg",
|
|
90
|
+
onClick: (e) => e.stopPropagation()
|
|
91
|
+
}), /* @__PURE__ */ f("button", {
|
|
92
|
+
type: "button",
|
|
93
|
+
onClick: (e) => {
|
|
94
|
+
e.stopPropagation(), M();
|
|
95
|
+
},
|
|
96
|
+
className: "p-1 hover:bg-bg-sunken rounded",
|
|
97
|
+
"aria-label": m("conversations.saveTitle", "Save title"),
|
|
98
|
+
children: /* @__PURE__ */ f(a, { className: "size-3 text-status-success-text" })
|
|
99
|
+
})]
|
|
100
|
+
}) : /* @__PURE__ */ p(d, { children: [
|
|
101
|
+
/* @__PURE__ */ p("div", {
|
|
102
|
+
className: "flex items-center justify-between",
|
|
103
|
+
children: [/* @__PURE__ */ f("span", {
|
|
104
|
+
className: "text-xs font-medium text-text-primary truncate flex-1",
|
|
105
|
+
children: t.title
|
|
106
|
+
}), /* @__PURE__ */ p("div", {
|
|
107
|
+
className: "hidden group-hover:flex group-focus-within:flex items-center gap-0.5 ml-1",
|
|
108
|
+
children: [/* @__PURE__ */ f("button", {
|
|
109
|
+
type: "button",
|
|
110
|
+
onClick: (e) => {
|
|
111
|
+
e.stopPropagation(), j(t.id, t.title);
|
|
112
|
+
},
|
|
113
|
+
className: "p-0.5 hover:bg-bg-sunken rounded",
|
|
114
|
+
"aria-label": m("conversations.rename", "Rename conversation"),
|
|
115
|
+
children: /* @__PURE__ */ f(c, { className: "size-3 text-text-muted" })
|
|
116
|
+
}), /* @__PURE__ */ f("button", {
|
|
117
|
+
type: "button",
|
|
118
|
+
onClick: (e) => N(e, t.id),
|
|
119
|
+
className: "p-0.5 hover:bg-bg-sunken rounded",
|
|
120
|
+
"aria-label": m("conversations.delete", "Delete conversation"),
|
|
121
|
+
"data-testid": "delete-conversation",
|
|
122
|
+
children: /* @__PURE__ */ f(u, { className: "size-3 text-status-error-text" })
|
|
123
|
+
})]
|
|
124
|
+
})]
|
|
125
|
+
}),
|
|
126
|
+
/* @__PURE__ */ p("div", {
|
|
127
|
+
className: "flex items-center gap-1.5 mt-0.5",
|
|
128
|
+
children: [
|
|
129
|
+
/* @__PURE__ */ f("span", {
|
|
130
|
+
className: "text-[10px] text-text-muted px-1 py-0.5 bg-bg-sunken rounded",
|
|
131
|
+
children: i?.label ?? t.mode
|
|
132
|
+
}),
|
|
133
|
+
/* @__PURE__ */ p("span", {
|
|
134
|
+
className: "text-[10px] text-text-muted",
|
|
135
|
+
children: [o.length, " msgs"]
|
|
136
|
+
}),
|
|
137
|
+
g && g.status !== "idle" && /* @__PURE__ */ f("span", {
|
|
138
|
+
className: "text-[10px] text-action-primary-bg px-1 py-0.5 bg-bg-sunken rounded",
|
|
139
|
+
children: g.status
|
|
140
|
+
})
|
|
141
|
+
]
|
|
142
|
+
}),
|
|
143
|
+
s && /* @__PURE__ */ f("p", {
|
|
144
|
+
className: "text-[10px] text-text-muted truncate mt-0.5",
|
|
145
|
+
children: s.content.slice(0, 60)
|
|
146
|
+
}),
|
|
147
|
+
l && /* @__PURE__ */ f("p", {
|
|
148
|
+
className: "text-[10px] text-text-muted truncate mt-0.5",
|
|
149
|
+
children: m("conversationList.voiceOnly", "Spoken conversation")
|
|
150
|
+
})
|
|
151
|
+
] })
|
|
152
|
+
}, t.id);
|
|
153
|
+
})
|
|
154
|
+
})
|
|
155
|
+
})]
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
//#endregion
|
|
159
|
+
export { m as AssistantConversationList };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { AssistantMode } from '../types';
|
|
3
|
+
interface Props {
|
|
4
|
+
mode: AssistantMode;
|
|
5
|
+
onSuggestionClick: (suggestion: string) => void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* AssistantEmptyState — the v2 zero-message surface (per the "panel-welcome"
|
|
9
|
+
* mockup): a centered gradient sparkle mark, one headline, one contextual
|
|
10
|
+
* sentence, and 3–4 rounded suggestion chips. Shown only while a conversation
|
|
11
|
+
* has no messages (AssistantChatArea swaps it for the transcript once messages
|
|
12
|
+
* exist). Derived from the former AssistantWelcome.
|
|
13
|
+
*/
|
|
14
|
+
export declare const AssistantEmptyState: FC<Props>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=AssistantEmptyState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantEmptyState.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantEmptyState.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAI9C,UAAU,KAAK;IACb,IAAI,EAAE,aAAa,CAAC;IACpB,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,KAAK,CA2DzC,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { resolveModeConfig as e, useAssistantProduct as t } from "../product.js";
|
|
2
|
+
import { useAssistantTr as n } from "../i18n.js";
|
|
3
|
+
import { useMemo as r } from "react";
|
|
4
|
+
import { Sparkles as i } from "lucide-react";
|
|
5
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
6
|
+
//#region src/shared/assistant/ui/AssistantEmptyState.tsx
|
|
7
|
+
var s = ({ mode: s, onSuggestionClick: c }) => {
|
|
8
|
+
let l = n(), { modes: u, describeCurrentPage: d } = t(), f = e(u, s), p = r(() => d?.() ?? null, [d]), m = f?.suggestions.slice(0, 4) ?? [];
|
|
9
|
+
return /* @__PURE__ */ o("div", {
|
|
10
|
+
className: "flex flex-1 flex-col items-center justify-center overflow-y-auto px-6 py-8 text-center",
|
|
11
|
+
children: [
|
|
12
|
+
/* @__PURE__ */ a("div", {
|
|
13
|
+
className: "flex size-12 items-center justify-center rounded-2xl bg-gradient-to-br from-action-primary-bg/25 to-action-primary-bg/5 text-action-primary-bg shadow-sm",
|
|
14
|
+
children: /* @__PURE__ */ a(i, { className: "size-6" })
|
|
15
|
+
}),
|
|
16
|
+
/* @__PURE__ */ a("h2", {
|
|
17
|
+
className: "mt-5 text-2xl font-semibold leading-tight tracking-tight text-text-primary",
|
|
18
|
+
children: l("empty.title", "How can I help?")
|
|
19
|
+
}),
|
|
20
|
+
/* @__PURE__ */ a("p", {
|
|
21
|
+
className: "mt-2 max-w-[16rem] text-[13px] leading-relaxed text-text-muted",
|
|
22
|
+
children: p ? l("empty.subtitle", "You're viewing {{page}}. Ask about it, or pick a suggestion below.", { page: p }) : l("empty.subtitleNoPage", "Ask me anything, or pick a suggestion below.")
|
|
23
|
+
}),
|
|
24
|
+
/* @__PURE__ */ a("div", {
|
|
25
|
+
className: "mt-6 flex flex-wrap items-center justify-center gap-2",
|
|
26
|
+
children: m.map((e) => /* @__PURE__ */ a("button", {
|
|
27
|
+
type: "button",
|
|
28
|
+
onClick: () => c(e),
|
|
29
|
+
className: "rounded-full border border-border-subtle bg-bg-surface px-3.5 py-2 text-[13px] leading-tight text-text-primary shadow-sm transition-all hover:border-action-primary-bg/40 hover:bg-bg-elevated hover:shadow-md",
|
|
30
|
+
"data-testid": "assistant-suggestion",
|
|
31
|
+
children: e
|
|
32
|
+
}, e))
|
|
33
|
+
})
|
|
34
|
+
]
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
//#endregion
|
|
38
|
+
export { s as AssistantEmptyState };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Friendly label for the page the user is on (e.g. "Inventory"). */
|
|
4
|
+
contextLabel: string;
|
|
5
|
+
onNewConversation: () => void;
|
|
6
|
+
onOpenHistory: () => void;
|
|
7
|
+
/** True when the history drawer is currently open (drives the toggle state). */
|
|
8
|
+
historyOpen: boolean;
|
|
9
|
+
onClose: () => void;
|
|
10
|
+
docked?: boolean;
|
|
11
|
+
onToggleDock?: () => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* AssistantHeader — the v2 identity bar (per the ai-assistant-v2 mockups):
|
|
15
|
+
* a ✦ brand mark + "HealthyBowl AI", a small availability/context subtitle
|
|
16
|
+
* ("Ready · Context: <page>"), and a row of icon actions: New conversation,
|
|
17
|
+
* History (opens the conversation list as an overlay drawer — NOT an accordion),
|
|
18
|
+
* Export, Dock toggle, Close.
|
|
19
|
+
*
|
|
20
|
+
* Replaces the old "Conversation History" accordion header. HB semantic tokens
|
|
21
|
+
* only; copy via useAssistantTr.
|
|
22
|
+
*/
|
|
23
|
+
export declare const AssistantHeader: FC<Props>;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=AssistantHeader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantHeader.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAYhC,UAAU,KAAK;IACb,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,gFAAgF;IAChF,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,KAAK,CA8FrC,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { useAssistantTr as e } from "../i18n.js";
|
|
2
|
+
import { AssistantMoreMenu as t } from "./AssistantMoreMenu.js";
|
|
3
|
+
import { History as n, PanelBottom as r, PanelRight as i, Plus as a, Sparkles as o, X as s } from "lucide-react";
|
|
4
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
5
|
+
//#region src/shared/assistant/ui/AssistantHeader.tsx
|
|
6
|
+
var u = ({ contextLabel: u, onNewConversation: d, onOpenHistory: f, historyOpen: p, onClose: m, docked: h, onToggleDock: g }) => {
|
|
7
|
+
let _ = e();
|
|
8
|
+
return /* @__PURE__ */ l("div", {
|
|
9
|
+
className: "flex items-center gap-2 border-b border-border-default bg-bg-elevated px-3 py-2.5",
|
|
10
|
+
children: [/* @__PURE__ */ l("div", {
|
|
11
|
+
className: "flex min-w-0 flex-1 items-center gap-2",
|
|
12
|
+
children: [/* @__PURE__ */ c("span", {
|
|
13
|
+
className: "flex size-7 flex-shrink-0 items-center justify-center rounded-lg bg-gradient-to-br from-action-primary-bg/25 to-action-primary-bg/5 text-action-primary-bg",
|
|
14
|
+
children: /* @__PURE__ */ c(o, { className: "size-4" })
|
|
15
|
+
}), /* @__PURE__ */ l("span", {
|
|
16
|
+
className: "min-w-0 flex-1",
|
|
17
|
+
children: [/* @__PURE__ */ c("span", {
|
|
18
|
+
className: "block truncate text-[14px] font-semibold leading-tight text-text-primary",
|
|
19
|
+
children: _("header.title", "HealthyBowl AI")
|
|
20
|
+
}), /* @__PURE__ */ l("span", {
|
|
21
|
+
className: "block truncate text-[11px] leading-tight text-text-muted",
|
|
22
|
+
children: [
|
|
23
|
+
_("header.ready", "Ready"),
|
|
24
|
+
/* @__PURE__ */ c("span", {
|
|
25
|
+
"aria-hidden": "true",
|
|
26
|
+
children: " · "
|
|
27
|
+
}),
|
|
28
|
+
_("header.context", "Context: {{page}}", { page: u })
|
|
29
|
+
]
|
|
30
|
+
})]
|
|
31
|
+
})]
|
|
32
|
+
}), /* @__PURE__ */ l("div", {
|
|
33
|
+
className: "flex flex-shrink-0 items-center gap-0.5",
|
|
34
|
+
children: [
|
|
35
|
+
/* @__PURE__ */ c("button", {
|
|
36
|
+
type: "button",
|
|
37
|
+
onClick: d,
|
|
38
|
+
className: "rounded-lg p-1.5 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary",
|
|
39
|
+
"aria-label": _("header.newConversation", "New conversation"),
|
|
40
|
+
"data-testid": "assistant-new-conversation",
|
|
41
|
+
children: /* @__PURE__ */ c(a, { className: "size-4" })
|
|
42
|
+
}),
|
|
43
|
+
/* @__PURE__ */ c("button", {
|
|
44
|
+
type: "button",
|
|
45
|
+
onClick: f,
|
|
46
|
+
className: `rounded-lg p-1.5 transition-colors ${p ? "bg-action-primary-bg/15 text-action-primary-bg" : "text-text-secondary hover:bg-bg-sunken hover:text-text-primary"}`,
|
|
47
|
+
"aria-label": _("header.history", "Conversation history"),
|
|
48
|
+
"aria-pressed": p,
|
|
49
|
+
"data-testid": "assistant-open-history",
|
|
50
|
+
children: /* @__PURE__ */ c(n, { className: "size-4" })
|
|
51
|
+
}),
|
|
52
|
+
/* @__PURE__ */ c(t, {}),
|
|
53
|
+
g && /* @__PURE__ */ c("button", {
|
|
54
|
+
type: "button",
|
|
55
|
+
onClick: g,
|
|
56
|
+
className: "hidden rounded-lg p-1.5 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary sm:inline-flex",
|
|
57
|
+
"aria-label": h ? _("header.float", "Float chat window") : _("header.dock", "Dock to side panel"),
|
|
58
|
+
"aria-pressed": h,
|
|
59
|
+
"data-testid": "assistant-toggle-dock",
|
|
60
|
+
children: c(h ? r : i, { className: "size-4" })
|
|
61
|
+
}),
|
|
62
|
+
/* @__PURE__ */ c("button", {
|
|
63
|
+
type: "button",
|
|
64
|
+
onClick: m,
|
|
65
|
+
className: "rounded-lg p-1.5 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary",
|
|
66
|
+
"aria-label": _("header.close", "Close assistant"),
|
|
67
|
+
"data-testid": "assistant-close",
|
|
68
|
+
children: /* @__PURE__ */ c(s, { className: "size-4" })
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
})]
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
//#endregion
|
|
75
|
+
export { u as AssistantHeader };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The header's secondary surface — everything that CONFIGURES the assistant.
|
|
4
|
+
*
|
|
5
|
+
* ★ `+` supplies content, `⋯` configures. Keeping those two meanings apart is
|
|
6
|
+
* the point: the header carried seven controls, and three of them
|
|
7
|
+
* (auto-read, the voice picker, export) render null under conditions the user
|
|
8
|
+
* cannot see — no speech support, fewer than two voices, an empty conversation —
|
|
9
|
+
* so the row silently changed width between devices and between the first and
|
|
10
|
+
* second message of the same session.
|
|
11
|
+
*
|
|
12
|
+
* Now four primary controls, always present, and one menu that absorbs the
|
|
13
|
+
* conditional ones. A menu ROW may still hide itself; a menu that keeps its
|
|
14
|
+
* position while its contents vary is a much smaller surprise than a toolbar
|
|
15
|
+
* that reflows.
|
|
16
|
+
*
|
|
17
|
+
* ★ Export is FLATTENED into this menu rather than nested inside it. It was
|
|
18
|
+
* itself a dropdown, and a dropdown inside a dropdown is two Escape presses and
|
|
19
|
+
* two outside-click regions for two menu items.
|
|
20
|
+
*
|
|
21
|
+
* ★ The voice picker keeps its native `<select>`. It is deliberate — see that
|
|
22
|
+
* component — and a custom listbox would look tidier in a screenshot while being
|
|
23
|
+
* worse on the phones this product is used on. Because the select lives inside
|
|
24
|
+
* the menu's own subtree, the outside-click handler ignores clicks on it.
|
|
25
|
+
*
|
|
26
|
+
* Not included, deliberately: Live captions and Assistant settings have nothing
|
|
27
|
+
* behind them yet, and a Transcript entry needs a product decision first (the
|
|
28
|
+
* voice transcript is session-scoped, while the chat thread is always visible —
|
|
29
|
+
* one menu label cannot honestly mean both).
|
|
30
|
+
*/
|
|
31
|
+
export declare const AssistantMoreMenu: FC;
|
|
32
|
+
//# sourceMappingURL=AssistantMoreMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantMoreMenu.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantMoreMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAgB7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAgM/B,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { useAssistantTr as e } from "../i18n.js";
|
|
2
|
+
import { useAssistantStore as t } from "../store.js";
|
|
3
|
+
import { useAssistantSpeech as n } from "./AssistantSpeechProvider.js";
|
|
4
|
+
import { AssistantReplyLanguageSelector as r } from "./AssistantReplyLanguageSelector.js";
|
|
5
|
+
import { AssistantVoiceSelector as i } from "./composer/AssistantVoiceSelector.js";
|
|
6
|
+
import { downloadFile as a, exportConversation as o } from "../exportConversation.js";
|
|
7
|
+
import { useEffect as s, useRef as c, useState as l } from "react";
|
|
8
|
+
import { Check as u, FileJson as d, FileText as f, MoreHorizontal as p, Play as m, Volume2 as h } from "lucide-react";
|
|
9
|
+
import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
10
|
+
//#region src/shared/assistant/ui/AssistantMoreMenu.tsx
|
|
11
|
+
var y = () => {
|
|
12
|
+
let y = e(), [b, x] = l(!1), S = c(null), C = c(null), { conversations: w, activeConversationId: T } = t(), E = w.find((e) => e.id === T), D = !!(E && E.messages.length > 0), { isSupported: O, isBlocked: k, disabledReason: A, autoSpeakEnabled: j, setAutoSpeak: M, stop: N, previewVoice: P, activeVoiceName: F } = n(), I = k && !j;
|
|
13
|
+
s(() => {
|
|
14
|
+
if (!b) return;
|
|
15
|
+
let e = (e) => {
|
|
16
|
+
e.key === "Escape" && (x(!1), C.current?.focus());
|
|
17
|
+
}, t = (e) => {
|
|
18
|
+
let t = e.target;
|
|
19
|
+
S.current?.contains(t) || C.current?.contains(t) || x(!1);
|
|
20
|
+
};
|
|
21
|
+
return window.addEventListener("keydown", e), document.addEventListener("mousedown", t), () => {
|
|
22
|
+
window.removeEventListener("keydown", e), document.removeEventListener("mousedown", t);
|
|
23
|
+
};
|
|
24
|
+
}, [b]);
|
|
25
|
+
let L = (e) => {
|
|
26
|
+
if (!E) return;
|
|
27
|
+
let { content: t, filename: n, mimeType: r } = o(E, e);
|
|
28
|
+
a(t, n, r), x(!1);
|
|
29
|
+
}, R = () => {
|
|
30
|
+
j && N(), M(!j);
|
|
31
|
+
}, z = y("header.more", "More options");
|
|
32
|
+
return /* @__PURE__ */ v("div", {
|
|
33
|
+
className: "relative",
|
|
34
|
+
children: [/* @__PURE__ */ _("button", {
|
|
35
|
+
ref: C,
|
|
36
|
+
type: "button",
|
|
37
|
+
onClick: () => x((e) => !e),
|
|
38
|
+
className: "rounded p-1 transition-colors hover:bg-bg-elevated",
|
|
39
|
+
"aria-label": z,
|
|
40
|
+
"aria-haspopup": "menu",
|
|
41
|
+
"aria-expanded": b,
|
|
42
|
+
"data-testid": "assistant-more",
|
|
43
|
+
children: /* @__PURE__ */ _(p, { className: "size-4 text-text-secondary" })
|
|
44
|
+
}), b ? /* @__PURE__ */ v("div", {
|
|
45
|
+
ref: S,
|
|
46
|
+
role: "menu",
|
|
47
|
+
"aria-label": z,
|
|
48
|
+
className: "absolute right-0 top-full z-50 mt-1 min-w-56 overflow-hidden rounded-xl border border-border-default bg-bg-surface py-1 shadow-lg",
|
|
49
|
+
"data-testid": "assistant-more-menu",
|
|
50
|
+
children: [
|
|
51
|
+
O ? /* @__PURE__ */ v("button", {
|
|
52
|
+
type: "button",
|
|
53
|
+
role: "menuitemcheckbox",
|
|
54
|
+
"aria-checked": j,
|
|
55
|
+
onClick: R,
|
|
56
|
+
disabled: I,
|
|
57
|
+
title: I ? A ?? void 0 : void 0,
|
|
58
|
+
className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-xs text-text-primary transition-colors hover:bg-bg-elevated disabled:cursor-not-allowed disabled:text-text-muted disabled:hover:bg-transparent",
|
|
59
|
+
"data-testid": "assistant-auto-speak",
|
|
60
|
+
children: [
|
|
61
|
+
/* @__PURE__ */ _(h, {
|
|
62
|
+
className: "size-3.5 flex-shrink-0 text-text-secondary",
|
|
63
|
+
"aria-hidden": "true"
|
|
64
|
+
}),
|
|
65
|
+
/* @__PURE__ */ _("span", {
|
|
66
|
+
className: "flex-1",
|
|
67
|
+
children: y("header.autoRead", "Auto-read replies")
|
|
68
|
+
}),
|
|
69
|
+
j ? /* @__PURE__ */ _(u, { className: "size-3.5 flex-shrink-0 text-action-primary-bg" }) : null
|
|
70
|
+
]
|
|
71
|
+
}) : null,
|
|
72
|
+
/* @__PURE__ */ _(r, {}),
|
|
73
|
+
/* @__PURE__ */ v("div", {
|
|
74
|
+
className: "flex items-center gap-1 px-3 py-1.5",
|
|
75
|
+
"data-testid": "assistant-more-voice",
|
|
76
|
+
children: [/* @__PURE__ */ _(i, {}), F ? /* @__PURE__ */ v("button", {
|
|
77
|
+
type: "button",
|
|
78
|
+
onClick: () => P(F),
|
|
79
|
+
className: "flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] text-text-muted transition-colors hover:bg-bg-elevated hover:text-text-secondary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
|
|
80
|
+
"aria-label": y("voice.preview", "Hear this voice"),
|
|
81
|
+
"data-testid": "assistant-voice-preview",
|
|
82
|
+
children: [/* @__PURE__ */ _(m, {
|
|
83
|
+
className: "size-3",
|
|
84
|
+
"aria-hidden": "true"
|
|
85
|
+
}), y("voice.previewShort", "Preview")]
|
|
86
|
+
}) : null]
|
|
87
|
+
}),
|
|
88
|
+
D ? /* @__PURE__ */ v(g, { children: [
|
|
89
|
+
/* @__PURE__ */ _("div", {
|
|
90
|
+
className: "my-1 border-t border-border-subtle",
|
|
91
|
+
role: "separator"
|
|
92
|
+
}),
|
|
93
|
+
/* @__PURE__ */ v("button", {
|
|
94
|
+
type: "button",
|
|
95
|
+
role: "menuitem",
|
|
96
|
+
onClick: () => L("json"),
|
|
97
|
+
className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-xs text-text-primary transition-colors hover:bg-bg-elevated",
|
|
98
|
+
"data-testid": "export-json",
|
|
99
|
+
children: [/* @__PURE__ */ _(d, {
|
|
100
|
+
className: "size-3.5 flex-shrink-0 text-text-secondary",
|
|
101
|
+
"aria-hidden": "true"
|
|
102
|
+
}), y("export.json", "Export as JSON")]
|
|
103
|
+
}),
|
|
104
|
+
/* @__PURE__ */ v("button", {
|
|
105
|
+
type: "button",
|
|
106
|
+
role: "menuitem",
|
|
107
|
+
onClick: () => L("markdown"),
|
|
108
|
+
className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-xs text-text-primary transition-colors hover:bg-bg-elevated",
|
|
109
|
+
"data-testid": "export-markdown",
|
|
110
|
+
children: [/* @__PURE__ */ _(f, {
|
|
111
|
+
className: "size-3.5 flex-shrink-0 text-text-secondary",
|
|
112
|
+
"aria-hidden": "true"
|
|
113
|
+
}), y("export.markdown", "Export as Markdown")]
|
|
114
|
+
})
|
|
115
|
+
] }) : null
|
|
116
|
+
]
|
|
117
|
+
}) : null]
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
//#endregion
|
|
121
|
+
export { y as AssistantMoreMenu };
|
package/dist/shared-assistant.js
CHANGED
|
@@ -26,42 +26,48 @@ import { toCaptionText as kt } from "./shared/assistant/voice/captionText.js";
|
|
|
26
26
|
import { ASSISTANT_LANGUAGES as At, DEFAULT_SPEECH_RATE as jt, findAssistantLanguage as Mt, resolveAssistantLanguage as Nt } from "./shared/assistant/voice/languages.js";
|
|
27
27
|
import { replyFollowsInput as Pt, resolveLanguagePair as Ft } from "./shared/assistant/voice/languagePair.js";
|
|
28
28
|
import { findPendingWrite as It, parseConfirmationRefusal as Lt } from "./shared/assistant/pendingWrite.js";
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
import {
|
|
52
|
-
import {
|
|
53
|
-
import {
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
56
|
-
import {
|
|
57
|
-
import {
|
|
58
|
-
import {
|
|
59
|
-
import {
|
|
60
|
-
import {
|
|
61
|
-
import {
|
|
62
|
-
import {
|
|
63
|
-
import {
|
|
64
|
-
import {
|
|
65
|
-
import {
|
|
66
|
-
import {
|
|
67
|
-
|
|
29
|
+
import { AssistantProductProvider as Rt, resolveModeConfig as zt, useAssistantProduct as Bt, useAssistantProductOrNull as Vt } from "./shared/assistant/product.js";
|
|
30
|
+
import { AssistantI18nProvider as Ht, assistantTranslationKey as Ut, useAssistantI18nNamespace as Wt, useAssistantTr as Gt } from "./shared/assistant/i18n.js";
|
|
31
|
+
import { SPOKEN_LABEL_LANGUAGES as Kt, speechLabelsFor as qt } from "./shared/assistant/voice/speechLabels.js";
|
|
32
|
+
import { detectScriptLocale as Jt, resolveSpeechLocale as Yt } from "./shared/assistant/voice/replyLanguage.js";
|
|
33
|
+
import { IDLE_PLAYBACK as Xt, isSpeakingMessage as Zt, requiresCancel as Qt, speechPlaybackReducer as $t } from "./shared/assistant/voice/speechPlayback.js";
|
|
34
|
+
import { MAX_INLINE_IMAGE_BASE64_BYTES as en, MAX_REQUEST_BODY_BYTES as tn } from "./shared/assistant/gatewayLimits.js";
|
|
35
|
+
import { BOILERPLATE_PAGE_SHARE as nn, MAX_BOILERPLATE_LINE_CHARS as rn, MAX_EXTRACTED_CHARS as an, MAX_PDF_PAGES_SCANNED as on, MIN_PAGE_TEXT_CHARS as sn, MIN_TEXT_PAGE_SHARE as cn, columnLetterToIndex as ln, decodeXmlEntities as un, docxXmlToText as dn, fitPdfPages as fn, formatPageRanges as pn, isMostlyImagePages as mn, joinSheets as hn, pageMarker as gn, parseSharedStrings as _n, parseWorkbookSheets as vn, pdfTextItemsToPage as yn, sheetXmlToRows as bn, summarisePageText as xn, truncatePagesForInline as Sn } from "./shared/assistant/documentText.js";
|
|
36
|
+
import { ATTACHMENT_ACCEPT as Cn, AttachmentRejectedError as wn, INLINE_IMAGE_MAX_DIM as Tn, INLINE_IMAGE_QUALITY as En, MAX_ATTACHMENTS as Dn, MAX_FILE_BYTES as On, MAX_INLINE_CHARS_PER_FILE as kn, MAX_INLINE_CHARS_TOTAL as An, MAX_INLINE_IMAGE_BASE64_CHARS as jn, MAX_INLINE_IMAGE_PARTS as Mn, MAX_INLINE_TURN_BODY_BYTES as Nn, MAX_TURN_BODY_BYTES as Pn, PROMPT_ENVELOPE_RESERVE_BYTES as Fn, TURN_BODY_HEADROOM_BYTES as In, buildAttachmentPromptBlock as Ln, buildPromptParts as Rn, buildPromptWithAttachments as zn, classifyAttachment as Bn, countInlineImageCandidates as Vn, countInlinedImageParts as Hn, detectDocumentFormat as Un, estimateTurnBodyBytes as Wn, formatBytes as Gn, getAttachmentSendBlocker as Kn, getExtension as qn, getSendableAttachments as Jn, hasAttachmentWorkInFlight as Yn, parseDataUrl as Xn, toMessageAttachment as Zn, truncateForInline as Qn, validateFile as $n } from "./shared/assistant/attachments.js";
|
|
37
|
+
import { useAssistantStore as er } from "./shared/assistant/store.js";
|
|
38
|
+
import { isTurnInFlight as tr } from "./shared/assistant/turnState.js";
|
|
39
|
+
import { AssistantToolActivity as nr, parseToolActivity as rr } from "./shared/assistant/ui/AssistantToolActivity.js";
|
|
40
|
+
import { AssistantSpeechProvider as ir, useAssistantSpeech as ar } from "./shared/assistant/ui/AssistantSpeechProvider.js";
|
|
41
|
+
import { useVoiceSession as or } from "./shared/assistant/ui/useVoiceSession.js";
|
|
42
|
+
import { copyToClipboard as sr } from "./shared/assistant/clipboard.js";
|
|
43
|
+
import { getActorId as cr, getOrganizationId as lr, getWorkspaceId as ur } from "./shared/assistant/context.js";
|
|
44
|
+
import { ATTACHMENT_SOURCES as dr, availableAttachmentSources as fr, deviceHasCamera as pr } from "./shared/assistant/attachmentSources.js";
|
|
45
|
+
import { SANDBOX_READY_TTL_MS as mr, createReadinessTracker as hr, isRecentlyVerified as gr } from "./shared/assistant/sandboxReadiness.js";
|
|
46
|
+
import { AssistantAutoSpeakToggle as _r } from "./shared/assistant/ui/AssistantAutoSpeakToggle.js";
|
|
47
|
+
import { AssistantMarkdownImage as vr, imageHostLabel as yr, isRemoteImageSrc as br } from "./shared/assistant/ui/AssistantMarkdownImage.js";
|
|
48
|
+
import { AssistantMarkdownRenderer as xr, assistantUrlTransform as Sr } from "./shared/assistant/ui/AssistantMarkdownRenderer.js";
|
|
49
|
+
import { AssistantMessageAttachments as Cr } from "./shared/assistant/ui/AssistantMessageAttachments.js";
|
|
50
|
+
import { AssistantPendingWriteCard as wr } from "./shared/assistant/ui/AssistantPendingWriteCard.js";
|
|
51
|
+
import { AssistantReplyLanguageSelector as Tr } from "./shared/assistant/ui/AssistantReplyLanguageSelector.js";
|
|
52
|
+
import { AssistantSpeakButton as Er } from "./shared/assistant/ui/AssistantSpeakButton.js";
|
|
53
|
+
import { AssistantSpokenTurnsNotice as Dr } from "./shared/assistant/ui/AssistantSpokenTurnsNotice.js";
|
|
54
|
+
import { AssistantAttachmentButton as Or } from "./shared/assistant/ui/composer/AssistantAttachmentButton.js";
|
|
55
|
+
import { AssistantAttachmentChips as kr } from "./shared/assistant/ui/composer/AssistantAttachmentChips.js";
|
|
56
|
+
import { AssistantLanguageSelector as Ar, FOLLOW_APP_LOCALE as jr } from "./shared/assistant/ui/composer/AssistantLanguageSelector.js";
|
|
57
|
+
import { ASSISTANT_MODE_META as Mr, AssistantModeSelector as Nr, nextModeIndex as Pr } from "./shared/assistant/ui/composer/AssistantModeSelector.js";
|
|
58
|
+
import { AssistantVoiceButton as Fr } from "./shared/assistant/ui/composer/AssistantVoiceButton.js";
|
|
59
|
+
import { AUTO_VOICE as Ir, AssistantVoiceSelector as Lr } from "./shared/assistant/ui/composer/AssistantVoiceSelector.js";
|
|
60
|
+
import { AssistantVoiceOrb as Rr } from "./shared/assistant/ui/voice/AssistantVoiceOrb.js";
|
|
61
|
+
import { AssistantVoiceSessionButton as zr } from "./shared/assistant/ui/voice/AssistantVoiceSessionButton.js";
|
|
62
|
+
import { VoiceCaption as Br } from "./shared/assistant/ui/voice/VoiceCaption.js";
|
|
63
|
+
import { VoiceConversationView as Vr } from "./shared/assistant/ui/voice/VoiceConversationView.js";
|
|
64
|
+
import { VoiceWaveform as Hr } from "./shared/assistant/ui/voice/VoiceWaveform.js";
|
|
65
|
+
import { VoiceMiniController as Ur } from "./shared/assistant/ui/voice/VoiceMiniController.js";
|
|
66
|
+
import { VoiceStage as Wr } from "./shared/assistant/ui/voice/VoiceStage.js";
|
|
67
|
+
import { VoiceTranscriptDrawer as Gr } from "./shared/assistant/ui/voice/VoiceTranscriptDrawer.js";
|
|
68
|
+
import { downloadFile as Kr, exportConversation as qr } from "./shared/assistant/exportConversation.js";
|
|
69
|
+
import { AssistantMoreMenu as Jr } from "./shared/assistant/ui/AssistantMoreMenu.js";
|
|
70
|
+
import { AssistantHeader as Yr } from "./shared/assistant/ui/AssistantHeader.js";
|
|
71
|
+
import { AssistantConversationList as Xr } from "./shared/assistant/ui/AssistantConversationList.js";
|
|
72
|
+
import { AssistantEmptyState as Zr } from "./shared/assistant/ui/AssistantEmptyState.js";
|
|
73
|
+
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, 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, 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, r as isQuotaExhaustedError, Y as isReapedSandboxConnectionError, gr as isRecentlyVerified, X as isRecoverable, 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, Wt as useAssistantI18nNamespace, Bt as useAssistantProduct, Vt as useAssistantProductOrNull, ar as useAssistantSpeech, er as useAssistantStore, Gt as useAssistantTr, 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 };
|