@hanzo/rooms 0.1.74 → 0.1.75
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/Chat.js +13 -9
- package/dist/failure.d.ts +1 -1
- package/dist/failure.js +7 -6
- package/package.json +3 -3
package/dist/Chat.js
CHANGED
|
@@ -63,7 +63,7 @@ import { Share } from "./Share.js";
|
|
|
63
63
|
import { ConversationMenu, ThreadMore, useThreadList } from "./thread.js";
|
|
64
64
|
import { Schedule } from "./Schedule.js";
|
|
65
65
|
import { keepFile, useAttach, useKeep } from "./keep.js";
|
|
66
|
-
import { artifacts, lead, nameOf, PAGE, Panel, PanelToggle, prompt, renders, Reply, Served, Summary, useDeck, useKey, Suggestions, useCarry, useMind, useSuggestions, usePanel, frames, name as tabName, } from "@hanzo/build";
|
|
66
|
+
import { artifacts, lead, nameOf, PAGE, Panel, PanelToggle, prompt, renders, Reply, Served, Summary, useDeck, useKey, Suggestions, useCarry, useLanguage, useMind, useSuggestions, usePanel, frames, name as tabName, } from "@hanzo/build";
|
|
67
67
|
import { checkoutUrl } from './lib/pay.js';
|
|
68
68
|
import { Upgrade, useFree } from './Upgrade.js';
|
|
69
69
|
import { enter, LOGIN } from './lib/destination.js';
|
|
@@ -876,7 +876,9 @@ function Thread({ placeholder = message(), initial, anonymous = false, heading,
|
|
|
876
876
|
// as a transcript.
|
|
877
877
|
const { token } = useIamToken();
|
|
878
878
|
const ear = useMemo(() => speech({ ...base(), ...(token ? { token } : {}) }), [token]);
|
|
879
|
-
|
|
879
|
+
// The language dictation listens in: the person's own (Settings › General), or the browser's.
|
|
880
|
+
const [spoken, speakIn] = useLanguage(target);
|
|
881
|
+
const voice = useVoice({ speech: ear, ...(spoken ? { language: spoken } : {}), ...useDictation(draft, setDraft) });
|
|
880
882
|
// TALK MODE: a hands-free conversation on Hanzo's realtime socket, /v1/voice.
|
|
881
883
|
// The mic streams up, the answer streams back as speech with its words in
|
|
882
884
|
// `talk.reply`, and talking over it stops it. Its own conversation, so its
|
|
@@ -1242,7 +1244,7 @@ function Thread({ placeholder = message(), initial, anonymous = false, heading,
|
|
|
1242
1244
|
: how?.provider
|
|
1243
1245
|
? `${familyOf(model) || nameOf(model, listed)} is unavailable right now.`
|
|
1244
1246
|
: plainly(wrong, "this conversation");
|
|
1245
|
-
return (_jsx(Failure, { onRetry: resign || bill?.code === "free_plan_cap" ? undefined : () => speak(text, question.id), children: _jsxs(YStack, { gap: "$2", children: [_jsxs(Text, { fontSize: "$3", color: "$ink", children: [whom.length ? `No answer from ${join(whom)}. ` : "", said] }), how?.provider && wrong ? _jsx(Why, { text: detail(wrong) }) : null, !bill && (resign ||
|
|
1247
|
+
return (_jsx(Failure, { onRetry: resign || lift || bill?.code === "free_plan_cap" ? undefined : () => speak(text, question.id), children: _jsxs(YStack, { gap: "$2", children: [_jsxs(Text, { fontSize: "$3", color: "$ink", children: [whom.length ? `No answer from ${join(whom)}. ` : "", said] }), how?.provider && wrong ? _jsx(Why, { text: detail(wrong) }) : null, lift || (!bill && (resign || how?.wallet || how?.visitor)) ? (_jsx(XStack, { gap: "$2", flexWrap: "wrap", children: resign ? (_jsx(Button, { size: "sm", onClick: () => {
|
|
1246
1248
|
if (typeof window !== "undefined") {
|
|
1247
1249
|
localStorage.removeItem("hanzo_iam_access_token");
|
|
1248
1250
|
localStorage.removeItem("hanzo_iam_refresh_token");
|
|
@@ -1331,12 +1333,12 @@ function Thread({ placeholder = message(), initial, anonymous = false, heading,
|
|
|
1331
1333
|
if (!open)
|
|
1332
1334
|
setPlan(null);
|
|
1333
1335
|
}, prompt: plan ?? "", model: model, models: models.map((m) => ({ id: m.id, name: nameOf(m.id, listed) })) }), dragging ? (_jsx(YStack, { "aria-hidden": true, position: "absolute", t: 0, r: 0, b: 0, l: 0, z: 10, items: "center", justify: "center", bg: "var(--surface-scrim)", borderWidth: 2, borderStyle: "dashed", borderColor: "$borderColor", rounded: "var(--pane-round)", pointerEvents: "none", children: _jsxs(XStack, { items: "center", gap: "$2", px: "$4", py: "$2.5", rounded: "$10", bg: "$background", borderWidth: 1, borderColor: "$borderColor", children: [_jsx(Paperclip, { size: 15, "aria-hidden": true }), _jsx(Text, { fontSize: "$4", color: "$ink", children: "Drop files to attach" })] }) })) : null, _jsxs(XStack, { "data-slot": "conversation-head", height: 52, items: "center", justify: "space-between", gap: "$3", pl: "$4", pr: "$2", shrink: 0, children: [_jsxs(XStack, { items: "center", gap: "$2", minW: 0, flex: 1, children: [mine ? (_jsx(Text, { fontSize: 15, lineHeight: 20, color: "$ink", numberOfLines: 1, shrink: 1, minW: 0, children: mine.title || "Untitled" })) : null, room.length ? (_jsx(XStack, { role: "list", "aria-label": "Agents in this chat", items: "center", gap: "$1.5", minW: 0, overflowX: "auto", "$platform-web": { scrollbarWidth: "none" }, children: room.map((name) => (_jsxs(XStack, { role: "listitem", items: "center", gap: "$1.5", pl: "$1", pr: "$0.5", py: "$0.5", rounded: 999, borderWidth: 1, borderColor: "$borderColor", shrink: 0, children: [_jsx(Face, { src: faces[name]?.avatar ?? (name === withWhom ? portrait : undefined), emoji: faces[name]?.emoji ?? (name === withWhom ? persona?.emoji : undefined), name: name, size: 22 }), _jsx(Text, { fontSize: "$2", fontWeight: "600", color: "$color", numberOfLines: 1, display: "none", $sm: { display: "flex" }, children: name }), _jsx(Box, { render: "button", onClick: () => openAgent(name), "aria-label": `Remove ${name} from this chat`, title: `Remove ${name}`, width: 24, height: 24, rounded: 999, items: "center", justify: "center", hoverStyle: { bg: "$hover" }, children: _jsx(X, { size: 13, "aria-hidden": true, color: "var(--soft, var(--muted-foreground))" }) })] }, name))) })) : null] }), _jsxs(XStack, { "data-slot": "conversation-controls", items: "center", gap: 2, shrink: 0, children: [open ? _jsx(Share, { thread: open }) : null, mine ? (_jsx(ConversationMenu, { threads: alone, active: open, onSchedule: anonymous ? undefined : () => setPlan(lastAsked()), children: _jsx(XStack, { children: _jsx(ThreadMore, { t: mine }) }) })) : null, _jsx(Summary, { sections: sections, onOpen: () => setPanel(true) }), _jsx(PanelToggle, { open: panel, onToggle: () => setPanel(!panel) })] })] }), wide && aside !== null ? (_jsx(Beside, { children: _jsx(Panel, { side: deck, kinds: NONE, onHide: () => setPanel(false), label: "Tabs", ...browsing }) })) : null, !wide && panel ? _jsx(Panel, { side: deck, kinds: NONE, sheet: true, onHide: () => setPanel(false), label: "Tabs", ...browsing }) : null, isFree(model) ? (_jsxs(Text, { fontSize: "$2", color: "$soft", text: "center", maxW: MEASURE, mx: "auto", px: "$4", py: "$2", children: [freeCopy.notice, " ", _jsx(Anchor, { href: site("/legal/privacy"), children: freeCopy.noticeCta })] })) : null, _jsx(ChatSurface, { ...chat, messages: shown, send: guarded,
|
|
1334
|
-
// AN EMPTY ROOM CENTRES ITS COMPOSER. While nothing has been
|
|
1335
|
-
// opening (the heading
|
|
1336
|
-
//
|
|
1337
|
-
// the composer
|
|
1338
|
-
//
|
|
1339
|
-
center:
|
|
1336
|
+
// AN EMPTY ROOM CENTRES ITS COMPOSER on a laptop. While nothing has been
|
|
1337
|
+
// said the opening (the heading) and the composer sit as one group in the
|
|
1338
|
+
// middle of the height; the moment a turn exists the transcript takes the
|
|
1339
|
+
// height and the composer docks under it. A phone keeps it at the foot,
|
|
1340
|
+
// over the keyboard, from the first moment.
|
|
1341
|
+
center: media.sm,
|
|
1340
1342
|
// AS IT WAS WRITTEN. The package renders a turn's words plainly and
|
|
1341
1343
|
// says so — it ships no markdown pipeline because the plugin set is the
|
|
1342
1344
|
// surface's to choose — so an answer arrived here reading "```ts" with
|
|
@@ -1459,6 +1461,8 @@ function Thread({ placeholder = message(), initial, anonymous = false, heading,
|
|
|
1459
1461
|
limits,
|
|
1460
1462
|
onUpgrade: (id) => setAsk({ model: nameOf(id, listed) }),
|
|
1461
1463
|
voice,
|
|
1464
|
+
language: spoken,
|
|
1465
|
+
onLanguage: speakIn,
|
|
1462
1466
|
talk,
|
|
1463
1467
|
// While nothing has been said: what is worth doing next.
|
|
1464
1468
|
below: said.length === 0 && !anonymous ? _jsx(Suggestions, { rows: hints.rows, onPick: setDraft, onDismiss: hints.dismiss }) : undefined,
|
package/dist/failure.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare function plainly(error: unknown, subject: string): string;
|
|
|
25
25
|
*
|
|
26
26
|
* The gateway refuses a model the plan does not include with 402
|
|
27
27
|
* `plan_required`, a Free caller whose share is spent with 402
|
|
28
|
-
* `allowance_spent`, and a free request the shared pool cannot serve with 429
|
|
28
|
+
* (now 429) `allowance_spent`, and a free request the shared pool cannot serve with 429
|
|
29
29
|
* `pool_busy` or `pool_exhausted`, each with an `upgrade_url`. The code decides,
|
|
30
30
|
* never the sentence. The address is kept only when it is an https page on
|
|
31
31
|
* hanzo.ai or one of its hosts; any other leaves `href` empty and the caller
|
package/dist/failure.js
CHANGED
|
@@ -86,17 +86,18 @@ export function plainly(error, subject) {
|
|
|
86
86
|
* the pool spent for the window, and the pool every free user shares used up.
|
|
87
87
|
*/
|
|
88
88
|
const LIFTED = {
|
|
89
|
-
plan_required: 402,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
plan_required: [402],
|
|
90
|
+
// 429 since the gateway's free notice (object/free_notice.go); 402 before it.
|
|
91
|
+
allowance_spent: [402, 429],
|
|
92
|
+
pool_busy: [429],
|
|
93
|
+
pool_exhausted: [429],
|
|
93
94
|
};
|
|
94
95
|
/**
|
|
95
96
|
* Whether a refusal asks for a plan, and the checkout it names.
|
|
96
97
|
*
|
|
97
98
|
* The gateway refuses a model the plan does not include with 402
|
|
98
99
|
* `plan_required`, a Free caller whose share is spent with 402
|
|
99
|
-
* `allowance_spent`, and a free request the shared pool cannot serve with 429
|
|
100
|
+
* (now 429) `allowance_spent`, and a free request the shared pool cannot serve with 429
|
|
100
101
|
* `pool_busy` or `pool_exhausted`, each with an `upgrade_url`. The code decides,
|
|
101
102
|
* never the sentence. The address is kept only when it is an https page on
|
|
102
103
|
* hanzo.ai or one of its hosts; any other leaves `href` empty and the caller
|
|
@@ -105,7 +106,7 @@ const LIFTED = {
|
|
|
105
106
|
export function planRequired(error) {
|
|
106
107
|
const said = error?.body?.error;
|
|
107
108
|
const code = typeof said?.code === 'string' ? said.code : '';
|
|
108
|
-
if (!LIFTED[code]
|
|
109
|
+
if (!LIFTED[code]?.includes(status(error) ?? 0))
|
|
109
110
|
return null;
|
|
110
111
|
return { href: ours(said?.upgrade_url) };
|
|
111
112
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/rooms",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.75",
|
|
4
4
|
"description": "The workspace rooms — Home, Chat, Inbox, Contacts, Meet, Cal, Drive, Board, Work, Bots — and the frame that holds them, once, for every Hanzo surface.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@hanzo/ai": ">=0.6.23",
|
|
51
51
|
"@hanzo/appearance": ">=0.2.6",
|
|
52
|
-
"@hanzo/build": ">=0.2.
|
|
52
|
+
"@hanzo/build": ">=0.2.62",
|
|
53
53
|
"@hanzo/composer": ">=0.2.0",
|
|
54
54
|
"@hanzo/event": ">=0.3.56",
|
|
55
55
|
"@hanzo/gui": "^8.3.5",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@hanzo/ai": "0.6.23",
|
|
69
69
|
"@hanzo/appearance": "0.2.8",
|
|
70
|
-
"@hanzo/build": "0.2.
|
|
70
|
+
"@hanzo/build": "0.2.62",
|
|
71
71
|
"@hanzo/composer": "0.2.0",
|
|
72
72
|
"@hanzo/design": "0.5.34",
|
|
73
73
|
"@hanzo/event": "0.3.56",
|