@agent-native/core 0.79.24 → 0.79.26
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +18 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/AgentPanel.tsx +4 -0
- package/corpus/core/src/server/auth.ts +7 -0
- package/corpus/templates/assets/app/components/layout/Layout.tsx +21 -1
- package/corpus/templates/assets/app/hooks/use-image-model-menu.ts +74 -0
- package/corpus/templates/assets/app/routes/_index.tsx +4 -66
- package/corpus/templates/assets/app/routes/library.tsx +76 -41
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +40 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +10 -0
- package/dist/client/AgentPanel.d.ts +3 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +2 -2
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +2 -2
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +7 -7
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +8 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +1 -1
package/corpus/README.md
CHANGED
package/corpus/core/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @agent-native/core
|
|
2
2
|
|
|
3
|
+
## 0.79.26
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 27f630c: Fix Windows desktop (Tauri) email/password sign-in. The login endpoint now
|
|
8
|
+
returns the session token to the Windows WebView2 origin
|
|
9
|
+
(`http://tauri.localhost` / `https://tauri.localhost`), which was missing from
|
|
10
|
+
the desktop token allowlist, so sign-in no longer silently bounces back to the
|
|
11
|
+
form. Also stop reporting wrong-password failures as "Enter a valid email
|
|
12
|
+
address" — credential errors now surface as "Invalid email or password" while
|
|
13
|
+
genuine malformed-email input still gets the friendly format message.
|
|
14
|
+
|
|
15
|
+
## 0.79.25
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 8bac54f: Expose the optional image model menu through AgentSidebar so app sidebars can show secondary generation model controls.
|
|
20
|
+
|
|
3
21
|
## 0.79.24
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.79.
|
|
3
|
+
"version": "0.79.26",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -2340,6 +2340,8 @@ export interface AgentSidebarProps {
|
|
|
2340
2340
|
dynamicSuggestions?: AssistantChatProps["dynamicSuggestions"];
|
|
2341
2341
|
/** Optional controls rendered in the chat composer toolbar. */
|
|
2342
2342
|
composerToolbarSlot?: AssistantChatProps["composerToolbarSlot"];
|
|
2343
|
+
/** Optional secondary model menu shown inside the chat composer model picker. */
|
|
2344
|
+
imageModelMenu?: AssistantChatProps["imageModelMenu"];
|
|
2343
2345
|
/** Optional content rendered at the bottom of the chat thread. */
|
|
2344
2346
|
threadFooterSlot?: AssistantChatProps["threadFooterSlot"];
|
|
2345
2347
|
/** Initial sidebar width in pixels. Mount-only; user resize and a saved
|
|
@@ -2389,6 +2391,7 @@ export function AgentSidebar({
|
|
|
2389
2391
|
suggestions,
|
|
2390
2392
|
dynamicSuggestions,
|
|
2391
2393
|
composerToolbarSlot,
|
|
2394
|
+
imageModelMenu,
|
|
2392
2395
|
threadFooterSlot,
|
|
2393
2396
|
defaultSidebarWidth,
|
|
2394
2397
|
sidebarWidth,
|
|
@@ -2924,6 +2927,7 @@ export function AgentSidebar({
|
|
|
2924
2927
|
suggestions={suggestions}
|
|
2925
2928
|
dynamicSuggestions={dynamicSuggestions}
|
|
2926
2929
|
composerToolbarSlot={composerToolbarSlot}
|
|
2930
|
+
imageModelMenu={imageModelMenu}
|
|
2927
2931
|
threadFooterSlot={threadFooterSlot}
|
|
2928
2932
|
missingApiKeySetupLayout="sidebar"
|
|
2929
2933
|
onCollapse={() => setOpenPersisted(false)}
|
|
@@ -842,6 +842,11 @@ function publicAuthError(
|
|
|
842
842
|
}
|
|
843
843
|
|
|
844
844
|
function isAuthEmailValidationMessage(message: string): boolean {
|
|
845
|
+
// Credential failures (e.g. Better Auth's "Invalid email or password") mention
|
|
846
|
+
// "email" + "invalid" but are NOT email-format errors — don't rewrite them to
|
|
847
|
+
// the "enter a valid email" message, or every wrong-password attempt looks like
|
|
848
|
+
// a malformed-email error.
|
|
849
|
+
if (/password|credential/i.test(message)) return false;
|
|
845
850
|
return (
|
|
846
851
|
/\bemail\b/i.test(message) &&
|
|
847
852
|
/(invalid|input|required|format)/i.test(message)
|
|
@@ -1129,6 +1134,8 @@ const _desktopExchanges = new Map<string, DesktopExchangeEntry>();
|
|
|
1129
1134
|
const DESKTOP_EXCHANGE_ERROR_PREFIX = "__error__::";
|
|
1130
1135
|
const DESKTOP_AUTH_TOKEN_BODY_ORIGINS = new Set([
|
|
1131
1136
|
"tauri://localhost",
|
|
1137
|
+
"http://tauri.localhost",
|
|
1138
|
+
"https://tauri.localhost",
|
|
1132
1139
|
"http://localhost:1420",
|
|
1133
1140
|
]);
|
|
1134
1141
|
|
|
@@ -9,11 +9,16 @@ import {
|
|
|
9
9
|
useT,
|
|
10
10
|
} from "@agent-native/core/client";
|
|
11
11
|
import { InvitationBanner } from "@agent-native/core/client/org";
|
|
12
|
+
import {
|
|
13
|
+
EMBED_MODE_QUERY_PARAM,
|
|
14
|
+
EMBED_TOKEN_QUERY_PARAM,
|
|
15
|
+
} from "@agent-native/core/shared";
|
|
12
16
|
import { IconMenu2 } from "@tabler/icons-react";
|
|
13
17
|
import { useState, useEffect } from "react";
|
|
14
18
|
import { useLocation, useNavigate } from "react-router";
|
|
15
19
|
|
|
16
20
|
import { GenerationResults } from "@/components/generation/GenerationResults";
|
|
21
|
+
import { useImageModelMenu } from "@/hooks/use-image-model-menu";
|
|
17
22
|
import { useNavigationState } from "@/hooks/use-navigation-state";
|
|
18
23
|
import { ASSETS_CHAT_STORAGE_KEY } from "@/lib/chat";
|
|
19
24
|
import { cn } from "@/lib/utils";
|
|
@@ -35,11 +40,22 @@ function isEmbeddedWindow() {
|
|
|
35
40
|
}
|
|
36
41
|
}
|
|
37
42
|
|
|
43
|
+
function searchParamsEnableEmbeddedMode(search: string): boolean {
|
|
44
|
+
const params = new URLSearchParams(search);
|
|
45
|
+
const embedMode = params.get(EMBED_MODE_QUERY_PARAM);
|
|
46
|
+
return (
|
|
47
|
+
params.has(EMBED_TOKEN_QUERY_PARAM) ||
|
|
48
|
+
embedMode === "1" ||
|
|
49
|
+
embedMode === "true"
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
38
53
|
export function Layout({ children }: LayoutProps) {
|
|
39
54
|
useNavigationState();
|
|
40
55
|
const location = useLocation();
|
|
41
56
|
const navigate = useNavigate();
|
|
42
57
|
const t = useT();
|
|
58
|
+
const imageModelMenu = useImageModelMenu();
|
|
43
59
|
const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
|
|
44
60
|
const isCreateRoute =
|
|
45
61
|
location.pathname === "/" || location.pathname.startsWith("/chat/");
|
|
@@ -64,7 +80,10 @@ export function Layout({ children }: LayoutProps) {
|
|
|
64
80
|
location.pathname === "/extensions" ||
|
|
65
81
|
location.pathname.startsWith("/extensions/");
|
|
66
82
|
const chromeless =
|
|
67
|
-
(isPicker &&
|
|
83
|
+
(isPicker &&
|
|
84
|
+
(searchParamsEnableEmbeddedMode(location.search) ||
|
|
85
|
+
isEmbeddedWindow() ||
|
|
86
|
+
isEmbedAuthActive())) ||
|
|
68
87
|
location.pathname.endsWith("/embed");
|
|
69
88
|
|
|
70
89
|
if (chromeless) {
|
|
@@ -143,6 +162,7 @@ export function Layout({ children }: LayoutProps) {
|
|
|
143
162
|
threadFooterSlot={({ threadId }) => (
|
|
144
163
|
<GenerationResults threadId={threadId} />
|
|
145
164
|
)}
|
|
165
|
+
imageModelMenu={imageModelMenu}
|
|
146
166
|
>
|
|
147
167
|
{appFrame}
|
|
148
168
|
</AgentSidebar>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readClientAppState,
|
|
3
|
+
useT,
|
|
4
|
+
writeClientAppState,
|
|
5
|
+
} from "@agent-native/core/client";
|
|
6
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
7
|
+
|
|
8
|
+
// The composer's model picker shows the chat LLM (Claude/OpenAI/Gemini). The
|
|
9
|
+
// Assets app also drives a separate image model, so expose it as a secondary
|
|
10
|
+
// menu wherever Assets chat is mounted.
|
|
11
|
+
const IMAGE_MODEL_STATE_KEY = "imageGenerationModel";
|
|
12
|
+
const DEFAULT_IMAGE_MODEL = "gemini-3.1-flash-image";
|
|
13
|
+
const IMAGE_MODEL_OPTIONS = [
|
|
14
|
+
{
|
|
15
|
+
value: "gemini-3-pro-image",
|
|
16
|
+
modelName: "Gemini 3 Pro",
|
|
17
|
+
descriptorKey: "create.modelBestQuality",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
value: "gemini-3.1-flash-image",
|
|
21
|
+
modelName: "Gemini 3.1 Flash",
|
|
22
|
+
descriptorKey: "create.modelFast",
|
|
23
|
+
},
|
|
24
|
+
{ value: "gemini-2.5-flash-image", modelName: "Gemini 2.5 Flash" },
|
|
25
|
+
] as const;
|
|
26
|
+
|
|
27
|
+
export function useImageModelMenu() {
|
|
28
|
+
const t = useT();
|
|
29
|
+
const [imageModel, setImageModel] = useState<string>(DEFAULT_IMAGE_MODEL);
|
|
30
|
+
|
|
31
|
+
// Hydrate the saved image-model default so the picker reflects the user's
|
|
32
|
+
// last choice across sessions.
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
let cancelled = false;
|
|
35
|
+
void readClientAppState<{ model?: string }>(IMAGE_MODEL_STATE_KEY)
|
|
36
|
+
.then((state) => {
|
|
37
|
+
const stored = state?.model;
|
|
38
|
+
if (
|
|
39
|
+
!cancelled &&
|
|
40
|
+
stored &&
|
|
41
|
+
IMAGE_MODEL_OPTIONS.some((option) => option.value === stored)
|
|
42
|
+
) {
|
|
43
|
+
setImageModel(stored);
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
.catch(() => {});
|
|
47
|
+
return () => {
|
|
48
|
+
cancelled = true;
|
|
49
|
+
};
|
|
50
|
+
}, []);
|
|
51
|
+
|
|
52
|
+
const handleImageModelChange = useCallback((value: string) => {
|
|
53
|
+
setImageModel(value);
|
|
54
|
+
void writeClientAppState(IMAGE_MODEL_STATE_KEY, { model: value }).catch(
|
|
55
|
+
() => {},
|
|
56
|
+
);
|
|
57
|
+
}, []);
|
|
58
|
+
|
|
59
|
+
return useMemo(
|
|
60
|
+
() => ({
|
|
61
|
+
value: imageModel,
|
|
62
|
+
options: IMAGE_MODEL_OPTIONS.map((option) => ({
|
|
63
|
+
value: option.value,
|
|
64
|
+
label:
|
|
65
|
+
"descriptorKey" in option && option.descriptorKey
|
|
66
|
+
? `${option.modelName} · ${t(option.descriptorKey)}`
|
|
67
|
+
: option.modelName,
|
|
68
|
+
})),
|
|
69
|
+
onChange: handleImageModelChange,
|
|
70
|
+
label: t("create.imageModel"),
|
|
71
|
+
}),
|
|
72
|
+
[handleImageModelChange, imageModel, t],
|
|
73
|
+
);
|
|
74
|
+
}
|
|
@@ -2,40 +2,17 @@ import {
|
|
|
2
2
|
AgentChatSurface,
|
|
3
3
|
getBrowserTabId,
|
|
4
4
|
markAgentChatHomeHandoff,
|
|
5
|
-
readClientAppState,
|
|
6
5
|
sendToAgentChat,
|
|
7
6
|
useT,
|
|
8
|
-
writeClientAppState,
|
|
9
7
|
} from "@agent-native/core/client";
|
|
10
8
|
import { IconPhoto, IconSparkles, IconVideo } from "@tabler/icons-react";
|
|
11
|
-
import {
|
|
9
|
+
import { useEffect } from "react";
|
|
12
10
|
import { useNavigate, useParams } from "react-router";
|
|
13
11
|
|
|
14
12
|
import { GenerationResults } from "@/components/generation/GenerationResults";
|
|
13
|
+
import { useImageModelMenu } from "@/hooks/use-image-model-menu";
|
|
15
14
|
import { ASSETS_CHAT_STORAGE_KEY } from "@/lib/chat";
|
|
16
15
|
|
|
17
|
-
// The composer's model picker shows the chat LLM (Claude/OpenAI/Gemini). The
|
|
18
|
-
// Assets app also drives a separate *image* model, so we surface it in the same
|
|
19
|
-
// menu — otherwise "Claude" reads as the image generator, which it isn't. The
|
|
20
|
-
// choice persists in per-user application state so the generate-image action
|
|
21
|
-
// (server-side) can read it as the default model. Values must be valid
|
|
22
|
-
// IMAGE_MODELS ids from shared/api.
|
|
23
|
-
const IMAGE_MODEL_STATE_KEY = "imageGenerationModel";
|
|
24
|
-
const DEFAULT_IMAGE_MODEL = "gemini-3.1-flash-image";
|
|
25
|
-
const IMAGE_MODEL_OPTIONS = [
|
|
26
|
-
{
|
|
27
|
-
value: "gemini-3-pro-image",
|
|
28
|
-
modelName: "Gemini 3 Pro",
|
|
29
|
-
descriptorKey: "create.modelBestQuality",
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
value: "gemini-3.1-flash-image",
|
|
33
|
-
modelName: "Gemini 3.1 Flash",
|
|
34
|
-
descriptorKey: "create.modelFast",
|
|
35
|
-
},
|
|
36
|
-
{ value: "gemini-2.5-flash-image", modelName: "Gemini 2.5 Flash" },
|
|
37
|
-
] as const;
|
|
38
|
-
|
|
39
16
|
// Empty-state starters. Clicking one prefills the composer (without sending) so
|
|
40
17
|
// the user can finish the thought instead of staring at a chip that does
|
|
41
18
|
// nothing. `submit: false` = prefill only; `openSidebar: false` keeps focus on
|
|
@@ -81,7 +58,7 @@ export default function CreatePage() {
|
|
|
81
58
|
const { threadId } = useParams();
|
|
82
59
|
const navigate = useNavigate();
|
|
83
60
|
const t = useT();
|
|
84
|
-
const
|
|
61
|
+
const imageModelMenu = useImageModelMenu();
|
|
85
62
|
|
|
86
63
|
useEffect(() => {
|
|
87
64
|
function handleChatRunning(event: Event) {
|
|
@@ -96,34 +73,6 @@ export default function CreatePage() {
|
|
|
96
73
|
window.removeEventListener("agentNative.chatRunning", handleChatRunning);
|
|
97
74
|
}, []);
|
|
98
75
|
|
|
99
|
-
// Hydrate the saved image-model default so the picker reflects the user's
|
|
100
|
-
// last choice across sessions.
|
|
101
|
-
useEffect(() => {
|
|
102
|
-
let cancelled = false;
|
|
103
|
-
void readClientAppState<{ model?: string }>(IMAGE_MODEL_STATE_KEY)
|
|
104
|
-
.then((state) => {
|
|
105
|
-
const stored = state?.model;
|
|
106
|
-
if (
|
|
107
|
-
!cancelled &&
|
|
108
|
-
stored &&
|
|
109
|
-
IMAGE_MODEL_OPTIONS.some((option) => option.value === stored)
|
|
110
|
-
) {
|
|
111
|
-
setImageModel(stored);
|
|
112
|
-
}
|
|
113
|
-
})
|
|
114
|
-
.catch(() => {});
|
|
115
|
-
return () => {
|
|
116
|
-
cancelled = true;
|
|
117
|
-
};
|
|
118
|
-
}, []);
|
|
119
|
-
|
|
120
|
-
const handleImageModelChange = useCallback((value: string) => {
|
|
121
|
-
setImageModel(value);
|
|
122
|
-
void writeClientAppState(IMAGE_MODEL_STATE_KEY, { model: value }).catch(
|
|
123
|
-
() => {},
|
|
124
|
-
);
|
|
125
|
-
}, []);
|
|
126
|
-
|
|
127
76
|
return (
|
|
128
77
|
<div className="flex h-full min-h-0 flex-col bg-background">
|
|
129
78
|
<AgentChatSurface
|
|
@@ -141,18 +90,7 @@ export default function CreatePage() {
|
|
|
141
90
|
threadFooterSlot={({ threadId }) => (
|
|
142
91
|
<GenerationResults threadId={threadId} />
|
|
143
92
|
)}
|
|
144
|
-
imageModelMenu={
|
|
145
|
-
value: imageModel,
|
|
146
|
-
options: IMAGE_MODEL_OPTIONS.map((option) => ({
|
|
147
|
-
value: option.value,
|
|
148
|
-
label:
|
|
149
|
-
"descriptorKey" in option && option.descriptorKey
|
|
150
|
-
? `${option.modelName} · ${t(option.descriptorKey)}`
|
|
151
|
-
: option.modelName,
|
|
152
|
-
})),
|
|
153
|
-
onChange: handleImageModelChange,
|
|
154
|
-
label: t("create.imageModel"),
|
|
155
|
-
}}
|
|
93
|
+
imageModelMenu={imageModelMenu}
|
|
156
94
|
showHeader={false}
|
|
157
95
|
showTabBar={false}
|
|
158
96
|
dynamicSuggestions={false}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AgentToggleButton,
|
|
2
3
|
appPath,
|
|
3
4
|
getBrowserTabId,
|
|
4
5
|
getEmbedAuthToken,
|
|
@@ -18,6 +19,10 @@ import {
|
|
|
18
19
|
createEmbeddedAppBridge,
|
|
19
20
|
type EmbeddedAppBridge,
|
|
20
21
|
} from "@agent-native/core/embedding";
|
|
22
|
+
import {
|
|
23
|
+
EMBED_MODE_QUERY_PARAM,
|
|
24
|
+
EMBED_TOKEN_QUERY_PARAM,
|
|
25
|
+
} from "@agent-native/core/shared";
|
|
21
26
|
import {
|
|
22
27
|
IconArrowUpRight,
|
|
23
28
|
IconCheck,
|
|
@@ -114,6 +119,7 @@ const ASPECT_RATIOS = ["16:9", "1:1", "9:16", "4:3", "3:4", "21:9"] as const;
|
|
|
114
119
|
const GENERATION_COUNTS = [1, 2, 3, 4, 6] as const;
|
|
115
120
|
const STARTER_PRESET = DEFAULT_LIBRARY_PRESETS[0];
|
|
116
121
|
const STARTER_LIBRARY_ID = `starter:${STARTER_PRESET.id}`;
|
|
122
|
+
const MCP_APP_CHAT_BRIDGE_QUERY_PARAM = "__an_mcp_chat_bridge";
|
|
117
123
|
const PICKER_INLINE_SELECT_CLASS =
|
|
118
124
|
"h-7 w-auto min-w-0 max-w-full rounded-md border-0 bg-transparent px-1.5 py-1 text-xs font-medium text-muted-foreground shadow-none ring-offset-transparent transition hover:bg-accent/50 hover:text-foreground focus:ring-0 focus:ring-offset-0 sm:px-2 [&>svg]:ms-1 [&>svg]:size-3.5 [&>svg]:opacity-60";
|
|
119
125
|
type PickerMediaType = "image" | "video";
|
|
@@ -266,6 +272,24 @@ function normalizeCandidateRunIds(value: unknown): string[] | undefined {
|
|
|
266
272
|
return ids;
|
|
267
273
|
}
|
|
268
274
|
|
|
275
|
+
function searchParamsEnableEmbeddedLibrary(params: URLSearchParams): boolean {
|
|
276
|
+
const embedMode = params.get(EMBED_MODE_QUERY_PARAM);
|
|
277
|
+
return (
|
|
278
|
+
params.has(EMBED_TOKEN_QUERY_PARAM) ||
|
|
279
|
+
embedMode === "1" ||
|
|
280
|
+
embedMode === "true"
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function searchParamsRequestPicker(params: URLSearchParams): boolean {
|
|
285
|
+
const mcpChatBridge = params.get(MCP_APP_CHAT_BRIDGE_QUERY_PARAM);
|
|
286
|
+
return (
|
|
287
|
+
params.get("__an_picker") === "1" ||
|
|
288
|
+
mcpChatBridge === "1" ||
|
|
289
|
+
mcpChatBridge === "true"
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
|
|
269
293
|
function normalizeHostConfig(value: unknown): HostConfig {
|
|
270
294
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
271
295
|
const record = value as Record<string, unknown>;
|
|
@@ -870,6 +894,7 @@ function LibraryShellHeader({
|
|
|
870
894
|
aria-label={t("library.kitActions")}
|
|
871
895
|
/>
|
|
872
896
|
) : null}
|
|
897
|
+
<AgentToggleButton />
|
|
873
898
|
</div>
|
|
874
899
|
</div>
|
|
875
900
|
</header>
|
|
@@ -1277,7 +1302,7 @@ function AllAssetsBrowser() {
|
|
|
1277
1302
|
<button
|
|
1278
1303
|
type="button"
|
|
1279
1304
|
onClick={() => navigate(`/library/${asset.libraryId}`)}
|
|
1280
|
-
className="absolute bottom-2 left-2 z-10 max-w-[calc(100%-1rem)] truncate rounded-full bg-background/
|
|
1305
|
+
className="absolute bottom-2 left-2 z-10 max-w-[calc(100%-1rem)] truncate rounded-full bg-background/95 px-2.5 py-1 text-[11px] font-medium shadow-sm transition hover:bg-background"
|
|
1281
1306
|
>
|
|
1282
1307
|
{(asset as any).libraryTitle}
|
|
1283
1308
|
</button>
|
|
@@ -1292,7 +1317,7 @@ function AllAssetsBrowser() {
|
|
|
1292
1317
|
event.stopPropagation();
|
|
1293
1318
|
chooseAsset(asset);
|
|
1294
1319
|
}}
|
|
1295
|
-
className="absolute right-2 top-2 z-10 inline-flex h-8 w-8 items-center justify-center rounded-full bg-background/
|
|
1320
|
+
className="absolute right-2 top-2 z-10 inline-flex h-8 w-8 items-center justify-center rounded-full bg-background/90 text-foreground opacity-0 shadow-sm transition hover:bg-primary hover:text-primary-foreground focus:outline-none focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-ring group-hover:opacity-100"
|
|
1296
1321
|
>
|
|
1297
1322
|
<IconClipboard className="h-4 w-4" />
|
|
1298
1323
|
</button>
|
|
@@ -1892,32 +1917,34 @@ export function LibraryWorkspace({
|
|
|
1892
1917
|
return (
|
|
1893
1918
|
<div className="flex h-full min-h-0 flex-col bg-background text-foreground">
|
|
1894
1919
|
<section className="min-h-0 min-w-0 flex-1 overflow-hidden">
|
|
1895
|
-
|
|
1896
|
-
<
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1920
|
+
<div className="h-full min-h-0 min-w-0 overflow-y-auto">
|
|
1921
|
+
<LibraryShellHeader
|
|
1922
|
+
selectedLibraryId={routeSelectedLibraryId}
|
|
1923
|
+
libraries={libraries}
|
|
1924
|
+
isLoading={isLoading}
|
|
1925
|
+
onCreateKit={() => setCreateOpen(true)}
|
|
1926
|
+
/>
|
|
1927
|
+
{routeSelectedLibraryId || hasLibraries ? (
|
|
1928
|
+
<>
|
|
1929
|
+
<LibraryCandidateStage
|
|
1930
|
+
activeLibraryId={routeSelectedLibraryId}
|
|
1931
|
+
foldersByLibraryId={foldersByLibraryId}
|
|
1932
|
+
/>
|
|
1933
|
+
<div className="min-w-0">
|
|
1934
|
+
{routeSelectedLibraryId ? (
|
|
1935
|
+
<BrandKitDetailRoute
|
|
1936
|
+
libraryId={routeSelectedLibraryId}
|
|
1937
|
+
headerMode="actions"
|
|
1938
|
+
/>
|
|
1939
|
+
) : (
|
|
1940
|
+
<AllAssetsBrowser />
|
|
1941
|
+
)}
|
|
1942
|
+
</div>
|
|
1943
|
+
</>
|
|
1944
|
+
) : (
|
|
1945
|
+
<EmptyLibraryStarter onCreateBlank={() => setCreateOpen(true)} />
|
|
1946
|
+
)}
|
|
1947
|
+
</div>
|
|
1921
1948
|
</section>
|
|
1922
1949
|
<CreateLibraryDialog
|
|
1923
1950
|
open={createOpen}
|
|
@@ -1933,8 +1960,7 @@ export function AssetPickerSurface() {
|
|
|
1933
1960
|
const [searchParams] = useSearchParams();
|
|
1934
1961
|
const searchParamsKey = searchParams.toString();
|
|
1935
1962
|
const mcpChatBridgeActive =
|
|
1936
|
-
searchParams
|
|
1937
|
-
isEmbedMcpChatBridgeActive();
|
|
1963
|
+
searchParamsRequestPicker(searchParams) || isEmbedMcpChatBridgeActive();
|
|
1938
1964
|
const urlHostConfig = useMemo(() => {
|
|
1939
1965
|
const params = new URLSearchParams(searchParamsKey);
|
|
1940
1966
|
return {
|
|
@@ -1959,7 +1985,13 @@ export function AssetPickerSurface() {
|
|
|
1959
1985
|
} satisfies HostConfig;
|
|
1960
1986
|
}, [searchParamsKey]);
|
|
1961
1987
|
const bridgeRef = useRef<EmbeddedAppBridge | null>(null);
|
|
1962
|
-
const embedded = useMemo(
|
|
1988
|
+
const embedded = useMemo(
|
|
1989
|
+
() =>
|
|
1990
|
+
searchParamsEnableEmbeddedLibrary(searchParams) ||
|
|
1991
|
+
isEmbeddedWindow() ||
|
|
1992
|
+
isEmbedAuthActive(),
|
|
1993
|
+
[searchParams],
|
|
1994
|
+
);
|
|
1963
1995
|
const pickerVariantScopeId = useMemo(
|
|
1964
1996
|
() =>
|
|
1965
1997
|
typeof window === "undefined" ? null : `picker:${getBrowserTabId()}`,
|
|
@@ -2862,14 +2894,17 @@ export function AssetPickerSurface() {
|
|
|
2862
2894
|
</div>
|
|
2863
2895
|
)}
|
|
2864
2896
|
|
|
2865
|
-
{mediaType === "image" &&
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2897
|
+
{mediaType === "image" &&
|
|
2898
|
+
selectedLibraryId &&
|
|
2899
|
+
!usingStarterLibrary &&
|
|
2900
|
+
pickerVariantScopeId && (
|
|
2901
|
+
<LibraryCandidateStage
|
|
2902
|
+
activeLibraryId={selectedLibraryId}
|
|
2903
|
+
variantScopeId={pickerVariantScopeId}
|
|
2904
|
+
onUseAsset={chooseAsset}
|
|
2905
|
+
inline
|
|
2906
|
+
/>
|
|
2907
|
+
)}
|
|
2873
2908
|
|
|
2874
2909
|
{!selectedLibraryId && (
|
|
2875
2910
|
<div className="flex h-full items-center justify-center text-sm text-muted-foreground">
|
|
@@ -3070,8 +3105,8 @@ export default function LibraryRoute() {
|
|
|
3070
3105
|
const { pickerRequested, queryLibraryId } = useMemo(() => {
|
|
3071
3106
|
const params = new URLSearchParams(searchParamsKey);
|
|
3072
3107
|
const requested =
|
|
3073
|
-
params
|
|
3074
|
-
params
|
|
3108
|
+
searchParamsRequestPicker(params) ||
|
|
3109
|
+
searchParamsEnableEmbeddedLibrary(params);
|
|
3075
3110
|
return {
|
|
3076
3111
|
pickerRequested: requested,
|
|
3077
3112
|
queryLibraryId: requested ? null : params.get("libraryId"),
|
|
@@ -1881,6 +1881,40 @@ async function startNativeFullscreenRecording(
|
|
|
1881
1881
|
|
|
1882
1882
|
let uploadResult: NativeFullscreenUploadResult | null = null;
|
|
1883
1883
|
const viewUrl = `/r/${id}`;
|
|
1884
|
+
|
|
1885
|
+
// A native recording runs two ScreenCaptureKit streams: the screen
|
|
1886
|
+
// recorder and the whisper system-audio recognizer (system_audio.rs
|
|
1887
|
+
// opens its own SCStream with captures_audio). Tearing the transcription
|
|
1888
|
+
// stream down while the recorder is flushing its final `moov` atom
|
|
1889
|
+
// interrupts ScreenCaptureKit (RPRecordingErrorDomain -5814,
|
|
1890
|
+
// "Application connection interrupted"), so the recorder's
|
|
1891
|
+
// SCRecordingOutput aborts before the moov is written and the MP4 is left
|
|
1892
|
+
// permanently corrupt. The teardowns must be sequenced: recorder first,
|
|
1893
|
+
// transcription second.
|
|
1894
|
+
//
|
|
1895
|
+
// We also must not delay the recorder stop, or the clip keeps capturing
|
|
1896
|
+
// past the Stop click (Rust measures duration when the stop command
|
|
1897
|
+
// runs, and transcriptionCapture.stop() blocks on a ~1.5s settle).
|
|
1898
|
+
//
|
|
1899
|
+
// So: start the native finalize+upload now, which stops the recorder
|
|
1900
|
+
// capture immediately; wait for Rust to emit that the recorder has
|
|
1901
|
+
// finalized (moov written); only then tear the transcription stream
|
|
1902
|
+
// down. A timeout longer than the Rust finalize ceiling
|
|
1903
|
+
// (SCK_FINALIZE_TIMEOUT) guards against a lost event so Stop can never
|
|
1904
|
+
// hang.
|
|
1905
|
+
let signalRecorderFinalized: () => void = () => {};
|
|
1906
|
+
const recorderFinalized = new Promise<void>((resolve) => {
|
|
1907
|
+
signalRecorderFinalized = resolve;
|
|
1908
|
+
});
|
|
1909
|
+
const unlistenFinalized = await listen<string>(
|
|
1910
|
+
"clips:native-recording-finalized",
|
|
1911
|
+
(event) => {
|
|
1912
|
+
if (!event.payload || event.payload === id) {
|
|
1913
|
+
signalRecorderFinalized();
|
|
1914
|
+
}
|
|
1915
|
+
},
|
|
1916
|
+
);
|
|
1917
|
+
|
|
1884
1918
|
const uploadPromise = invoke<NativeFullscreenUploadResult>(
|
|
1885
1919
|
"native_fullscreen_recording_stop_and_upload",
|
|
1886
1920
|
{
|
|
@@ -1894,6 +1928,12 @@ async function startNativeFullscreenRecording(
|
|
|
1894
1928
|
);
|
|
1895
1929
|
uploadPromise.catch(() => {});
|
|
1896
1930
|
try {
|
|
1931
|
+
await Promise.race([
|
|
1932
|
+
recorderFinalized,
|
|
1933
|
+
new Promise<void>((resolve) => window.setTimeout(resolve, 15000)),
|
|
1934
|
+
]);
|
|
1935
|
+
unlistenFinalized();
|
|
1936
|
+
|
|
1897
1937
|
const capturedTranscript = await transcriptionCapture
|
|
1898
1938
|
?.stop()
|
|
1899
1939
|
.catch((err) => {
|
|
@@ -764,6 +764,16 @@ pub async fn native_fullscreen_recording_stop_and_upload(
|
|
|
764
764
|
multi_segment,
|
|
765
765
|
} = take_and_finalize_active_session(&state)?;
|
|
766
766
|
|
|
767
|
+
// The recorder's ScreenCaptureKit stream is now fully stopped and its moov
|
|
768
|
+
// atom is written (or has definitively failed). Signal the UI so it can tear
|
|
769
|
+
// down the separate live-transcription SCStream (system_audio.rs) now,
|
|
770
|
+
// without racing the recorder finalize: tearing that stream down while the
|
|
771
|
+
// recorder is still writing its moov interrupts ScreenCaptureKit
|
|
772
|
+
// (RPRecordingErrorDomain -5814) and corrupts the clip. Emitting here, before
|
|
773
|
+
// the slow upload, lets transcription stop promptly while the clip duration
|
|
774
|
+
// stays anchored to the real Stop click. See recorder.ts `handle.stop()`.
|
|
775
|
+
let _ = app.emit("clips:native-recording-finalized", &recording_id);
|
|
776
|
+
|
|
767
777
|
// The camera bubble is the ONE overlay we deliberately leave
|
|
768
778
|
// capture-included (see `show_bubble`), so it has to stay on-screen
|
|
769
779
|
// until the SCStream stops. Now that capture is finalized, tear it
|
|
@@ -132,6 +132,8 @@ export interface AgentSidebarProps {
|
|
|
132
132
|
dynamicSuggestions?: AssistantChatProps["dynamicSuggestions"];
|
|
133
133
|
/** Optional controls rendered in the chat composer toolbar. */
|
|
134
134
|
composerToolbarSlot?: AssistantChatProps["composerToolbarSlot"];
|
|
135
|
+
/** Optional secondary model menu shown inside the chat composer model picker. */
|
|
136
|
+
imageModelMenu?: AssistantChatProps["imageModelMenu"];
|
|
135
137
|
/** Optional content rendered at the bottom of the chat thread. */
|
|
136
138
|
threadFooterSlot?: AssistantChatProps["threadFooterSlot"];
|
|
137
139
|
/** Initial sidebar width in pixels. Mount-only; user resize and a saved
|
|
@@ -174,7 +176,7 @@ export interface AgentSidebarProps {
|
|
|
174
176
|
* Wraps app content with a toggleable agent sidebar.
|
|
175
177
|
* Use AgentToggleButton in your header to open/close it.
|
|
176
178
|
*/
|
|
177
|
-
export declare function AgentSidebar({ children, emptyStateText, suggestions, dynamicSuggestions, composerToolbarSlot, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position, defaultOpen, animateMobile, animateDesktop, chatViewTransition, storageKey, openOnChatRunning, onFullscreenRequest, scope, browserTabId, threadUrlSync, }: AgentSidebarProps): React.JSX.Element;
|
|
179
|
+
export declare function AgentSidebar({ children, emptyStateText, suggestions, dynamicSuggestions, composerToolbarSlot, imageModelMenu, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position, defaultOpen, animateMobile, animateDesktop, chatViewTransition, storageKey, openOnChatRunning, onFullscreenRequest, scope, browserTabId, threadUrlSync, }: AgentSidebarProps): React.JSX.Element;
|
|
178
180
|
/**
|
|
179
181
|
* Focus the agent chat composer input.
|
|
180
182
|
* Opens the sidebar if closed, then focuses the text input.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentPanel.d.ts","sourceRoot":"","sources":["../../src/client/AgentPanel.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"AgentPanel.d.ts","sourceRoot":"","sources":["../../src/client/AgentPanel.tsx"],"names":[],"mappings":"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"}
|